Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM NetDashboard.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AtomList.h"
4 : #include "NetDashboardBinding.h"
5 : #include "mozilla/FloatingPoint.h"
6 : #include "mozilla/OwningNonNull.h"
7 : #include "mozilla/dom/BindingUtils.h"
8 : #include "mozilla/dom/NonRefcountedDOMObject.h"
9 : #include "mozilla/dom/PrimitiveConversions.h"
10 : #include "mozilla/dom/ScriptSettings.h"
11 : #include "mozilla/dom/SimpleGlobalObject.h"
12 :
13 : namespace mozilla {
14 : namespace dom {
15 :
16 :
17 0 : ConnStatusDict::ConnStatusDict()
18 : {
19 : // Safe to pass a null context if we pass a null value
20 0 : Init(nullptr, JS::NullHandleValue);
21 0 : }
22 :
23 :
24 :
25 : bool
26 0 : ConnStatusDict::InitIds(JSContext* cx, ConnStatusDictAtoms* atomsCache)
27 : {
28 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
29 :
30 : // Initialize these in reverse order so that any failure leaves the first one
31 : // uninitialized.
32 0 : if (!atomsCache->status_id.init(cx, "status")) {
33 0 : return false;
34 : }
35 0 : return true;
36 : }
37 :
38 : bool
39 0 : ConnStatusDict::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
40 : {
41 : // Passing a null JSContext is OK only if we're initing from null,
42 : // Since in that case we will not have to do any property gets
43 : // Also evaluate isNullOrUndefined in order to avoid false-positive
44 : // checkers by static analysis tools
45 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
46 0 : ConnStatusDictAtoms* atomsCache = nullptr;
47 0 : if (cx) {
48 0 : atomsCache = GetAtomCache<ConnStatusDictAtoms>(cx);
49 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
50 0 : return false;
51 : }
52 : }
53 :
54 0 : if (!IsConvertibleToDictionary(val)) {
55 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
56 : }
57 :
58 0 : bool isNull = val.isNullOrUndefined();
59 : // We only need these if !isNull, in which case we have |cx|.
60 0 : Maybe<JS::Rooted<JSObject *> > object;
61 0 : Maybe<JS::Rooted<JS::Value> > temp;
62 0 : if (!isNull) {
63 0 : MOZ_ASSERT(cx);
64 0 : object.emplace(cx, &val.toObject());
65 0 : temp.emplace(cx);
66 : }
67 0 : if (!isNull) {
68 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->status_id, temp.ptr())) {
69 0 : return false;
70 : }
71 : }
72 0 : if (!isNull && !temp->isUndefined()) {
73 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mStatus)) {
74 0 : return false;
75 : }
76 : } else {
77 : static const char16_t data[] = { 0 };
78 0 : mStatus.Rebind(data, ArrayLength(data) - 1);
79 : }
80 0 : mIsAnyMemberPresent = true;
81 0 : return true;
82 : }
83 :
84 : bool
85 0 : ConnStatusDict::Init(const nsAString& aJSON)
86 : {
87 0 : AutoJSAPI jsapi;
88 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
89 0 : if (!cleanGlobal) {
90 0 : return false;
91 : }
92 0 : if (!jsapi.Init(cleanGlobal)) {
93 0 : return false;
94 : }
95 0 : JSContext* cx = jsapi.cx();
96 0 : JS::Rooted<JS::Value> json(cx);
97 0 : bool ok = ParseJSON(cx, aJSON, &json);
98 0 : NS_ENSURE_TRUE(ok, false);
99 0 : return Init(cx, json);
100 : }
101 :
102 : bool
103 0 : ConnStatusDict::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
104 : {
105 0 : ConnStatusDictAtoms* atomsCache = GetAtomCache<ConnStatusDictAtoms>(cx);
106 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
107 0 : return false;
108 : }
109 :
110 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
111 0 : if (!obj) {
112 0 : return false;
113 : }
114 0 : rval.set(JS::ObjectValue(*obj));
115 :
116 : do {
117 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
118 0 : JS::Rooted<JS::Value> temp(cx);
119 0 : nsString const & currentValue = mStatus;
120 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
121 0 : return false;
122 : }
123 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->status_id, temp, JSPROP_ENUMERATE)) {
124 0 : return false;
125 : }
126 0 : break;
127 : } while(0);
128 :
129 0 : return true;
130 : }
131 :
132 : bool
133 0 : ConnStatusDict::ToJSON(nsAString& aJSON) const
134 : {
135 0 : AutoJSAPI jsapi;
136 0 : jsapi.Init();
137 0 : JSContext *cx = jsapi.cx();
138 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
139 : // because we'll only be creating objects, in ways that have no
140 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
141 : // which likewise guarantees no side-effects for the sorts of
142 : // things we will pass it.
143 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
144 0 : JS::Rooted<JS::Value> val(cx);
145 0 : if (!ToObjectInternal(cx, &val)) {
146 0 : return false;
147 : }
148 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
149 0 : return StringifyToJSON(cx, obj, aJSON);
150 : }
151 :
152 : void
153 0 : ConnStatusDict::TraceDictionary(JSTracer* trc)
154 : {
155 0 : }
156 :
157 : ConnStatusDict&
158 0 : ConnStatusDict::operator=(const ConnStatusDict& aOther)
159 : {
160 0 : mStatus = aOther.mStatus;
161 0 : return *this;
162 : }
163 :
164 : namespace binding_detail {
165 : } // namespace binding_detail
166 :
167 :
168 :
169 0 : DNSLookupDict::DNSLookupDict()
170 : {
171 : // Safe to pass a null context if we pass a null value
172 0 : Init(nullptr, JS::NullHandleValue);
173 0 : }
174 :
175 :
176 :
177 : bool
178 0 : DNSLookupDict::InitIds(JSContext* cx, DNSLookupDictAtoms* atomsCache)
179 : {
180 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
181 :
182 : // Initialize these in reverse order so that any failure leaves the first one
183 : // uninitialized.
184 0 : if (!atomsCache->error_id.init(cx, "error") ||
185 0 : !atomsCache->answer_id.init(cx, "answer") ||
186 0 : !atomsCache->address_id.init(cx, "address")) {
187 0 : return false;
188 : }
189 0 : return true;
190 : }
191 :
192 : bool
193 0 : DNSLookupDict::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
194 : {
195 : // Passing a null JSContext is OK only if we're initing from null,
196 : // Since in that case we will not have to do any property gets
197 : // Also evaluate isNullOrUndefined in order to avoid false-positive
198 : // checkers by static analysis tools
199 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
200 0 : DNSLookupDictAtoms* atomsCache = nullptr;
201 0 : if (cx) {
202 0 : atomsCache = GetAtomCache<DNSLookupDictAtoms>(cx);
203 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
204 0 : return false;
205 : }
206 : }
207 :
208 0 : if (!IsConvertibleToDictionary(val)) {
209 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
210 : }
211 :
212 0 : bool isNull = val.isNullOrUndefined();
213 : // We only need these if !isNull, in which case we have |cx|.
214 0 : Maybe<JS::Rooted<JSObject *> > object;
215 0 : Maybe<JS::Rooted<JS::Value> > temp;
216 0 : if (!isNull) {
217 0 : MOZ_ASSERT(cx);
218 0 : object.emplace(cx, &val.toObject());
219 0 : temp.emplace(cx);
220 : }
221 0 : if (!isNull) {
222 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->address_id, temp.ptr())) {
223 0 : return false;
224 : }
225 : }
226 0 : if (!isNull && !temp->isUndefined()) {
227 0 : mAddress.Construct();
228 0 : if (temp.ref().isObject()) {
229 0 : JS::ForOfIterator iter(cx);
230 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
231 0 : return false;
232 : }
233 0 : if (!iter.valueIsIterable()) {
234 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'address' member of DNSLookupDict");
235 0 : return false;
236 : }
237 0 : Sequence<nsString> &arr = (mAddress.Value());
238 0 : JS::Rooted<JS::Value> temp(cx);
239 : while (true) {
240 : bool done;
241 0 : if (!iter.next(&temp, &done)) {
242 0 : return false;
243 : }
244 0 : if (done) {
245 0 : break;
246 : }
247 0 : nsString* slotPtr = arr.AppendElement(mozilla::fallible);
248 0 : if (!slotPtr) {
249 0 : JS_ReportOutOfMemory(cx);
250 0 : return false;
251 : }
252 0 : nsString& slot = *slotPtr;
253 0 : if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
254 0 : return false;
255 : }
256 0 : }
257 : } else {
258 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'address' member of DNSLookupDict");
259 0 : return false;
260 : }
261 0 : mIsAnyMemberPresent = true;
262 : }
263 :
264 0 : if (!isNull) {
265 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->answer_id, temp.ptr())) {
266 0 : return false;
267 : }
268 : }
269 0 : if (!isNull && !temp->isUndefined()) {
270 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mAnswer)) {
271 0 : return false;
272 : }
273 : } else {
274 0 : mAnswer = false;
275 : }
276 0 : mIsAnyMemberPresent = true;
277 :
278 0 : if (!isNull) {
279 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->error_id, temp.ptr())) {
280 0 : return false;
281 : }
282 : }
283 0 : if (!isNull && !temp->isUndefined()) {
284 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mError)) {
285 0 : return false;
286 : }
287 : } else {
288 : static const char16_t data[] = { 0 };
289 0 : mError.Rebind(data, ArrayLength(data) - 1);
290 : }
291 0 : mIsAnyMemberPresent = true;
292 0 : return true;
293 : }
294 :
295 : bool
296 0 : DNSLookupDict::Init(const nsAString& aJSON)
297 : {
298 0 : AutoJSAPI jsapi;
299 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
300 0 : if (!cleanGlobal) {
301 0 : return false;
302 : }
303 0 : if (!jsapi.Init(cleanGlobal)) {
304 0 : return false;
305 : }
306 0 : JSContext* cx = jsapi.cx();
307 0 : JS::Rooted<JS::Value> json(cx);
308 0 : bool ok = ParseJSON(cx, aJSON, &json);
309 0 : NS_ENSURE_TRUE(ok, false);
310 0 : return Init(cx, json);
311 : }
312 :
313 : bool
314 0 : DNSLookupDict::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
315 : {
316 0 : DNSLookupDictAtoms* atomsCache = GetAtomCache<DNSLookupDictAtoms>(cx);
317 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
318 0 : return false;
319 : }
320 :
321 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
322 0 : if (!obj) {
323 0 : return false;
324 : }
325 0 : rval.set(JS::ObjectValue(*obj));
326 :
327 0 : if (mAddress.WasPassed()) {
328 : do {
329 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
330 0 : JS::Rooted<JS::Value> temp(cx);
331 0 : Sequence<nsString> const & currentValue = mAddress.InternalValue();
332 :
333 0 : uint32_t length = currentValue.Length();
334 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
335 0 : if (!returnArray) {
336 0 : return false;
337 : }
338 : // Scope for 'tmp'
339 : {
340 0 : JS::Rooted<JS::Value> tmp(cx);
341 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
342 : // Control block to let us common up the JS_DefineElement calls when there
343 : // are different ways to succeed at wrapping the object.
344 : do {
345 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue[sequenceIdx0], &tmp)) {
346 0 : return false;
347 : }
348 0 : break;
349 : } while (0);
350 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
351 : JSPROP_ENUMERATE)) {
352 0 : return false;
353 : }
354 : }
355 : }
356 0 : temp.setObject(*returnArray);
357 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->address_id, temp, JSPROP_ENUMERATE)) {
358 0 : return false;
359 : }
360 0 : break;
361 : } while(0);
362 : }
363 :
364 : do {
365 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
366 0 : JS::Rooted<JS::Value> temp(cx);
367 0 : bool const & currentValue = mAnswer;
368 0 : temp.setBoolean(currentValue);
369 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->answer_id, temp, JSPROP_ENUMERATE)) {
370 0 : return false;
371 : }
372 0 : break;
373 : } while(0);
374 :
375 : do {
376 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
377 0 : JS::Rooted<JS::Value> temp(cx);
378 0 : nsString const & currentValue = mError;
379 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
380 0 : return false;
381 : }
382 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->error_id, temp, JSPROP_ENUMERATE)) {
383 0 : return false;
384 : }
385 0 : break;
386 : } while(0);
387 :
388 0 : return true;
389 : }
390 :
391 : bool
392 0 : DNSLookupDict::ToJSON(nsAString& aJSON) const
393 : {
394 0 : AutoJSAPI jsapi;
395 0 : jsapi.Init();
396 0 : JSContext *cx = jsapi.cx();
397 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
398 : // because we'll only be creating objects, in ways that have no
399 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
400 : // which likewise guarantees no side-effects for the sorts of
401 : // things we will pass it.
402 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
403 0 : JS::Rooted<JS::Value> val(cx);
404 0 : if (!ToObjectInternal(cx, &val)) {
405 0 : return false;
406 : }
407 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
408 0 : return StringifyToJSON(cx, obj, aJSON);
409 : }
410 :
411 : void
412 0 : DNSLookupDict::TraceDictionary(JSTracer* trc)
413 : {
414 0 : }
415 :
416 : DNSLookupDict&
417 0 : DNSLookupDict::operator=(const DNSLookupDict& aOther)
418 : {
419 0 : mAddress.Reset();
420 0 : if (aOther.mAddress.WasPassed()) {
421 0 : mAddress.Construct(aOther.mAddress.Value());
422 : }
423 0 : mAnswer = aOther.mAnswer;
424 0 : mError = aOther.mError;
425 0 : return *this;
426 : }
427 :
428 : namespace binding_detail {
429 : } // namespace binding_detail
430 :
431 :
432 :
433 0 : DnsCacheEntry::DnsCacheEntry()
434 : {
435 : // Safe to pass a null context if we pass a null value
436 0 : Init(nullptr, JS::NullHandleValue);
437 0 : }
438 :
439 :
440 :
441 : bool
442 0 : DnsCacheEntry::InitIds(JSContext* cx, DnsCacheEntryAtoms* atomsCache)
443 : {
444 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
445 :
446 : // Initialize these in reverse order so that any failure leaves the first one
447 : // uninitialized.
448 0 : if (!atomsCache->hostname_id.init(cx, "hostname") ||
449 0 : !atomsCache->hostaddr_id.init(cx, "hostaddr") ||
450 0 : !atomsCache->family_id.init(cx, "family") ||
451 0 : !atomsCache->expiration_id.init(cx, "expiration")) {
452 0 : return false;
453 : }
454 0 : return true;
455 : }
456 :
457 : bool
458 0 : DnsCacheEntry::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
459 : {
460 : // Passing a null JSContext is OK only if we're initing from null,
461 : // Since in that case we will not have to do any property gets
462 : // Also evaluate isNullOrUndefined in order to avoid false-positive
463 : // checkers by static analysis tools
464 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
465 0 : DnsCacheEntryAtoms* atomsCache = nullptr;
466 0 : if (cx) {
467 0 : atomsCache = GetAtomCache<DnsCacheEntryAtoms>(cx);
468 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
469 0 : return false;
470 : }
471 : }
472 :
473 0 : if (!IsConvertibleToDictionary(val)) {
474 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
475 : }
476 :
477 0 : bool isNull = val.isNullOrUndefined();
478 : // We only need these if !isNull, in which case we have |cx|.
479 0 : Maybe<JS::Rooted<JSObject *> > object;
480 0 : Maybe<JS::Rooted<JS::Value> > temp;
481 0 : if (!isNull) {
482 0 : MOZ_ASSERT(cx);
483 0 : object.emplace(cx, &val.toObject());
484 0 : temp.emplace(cx);
485 : }
486 0 : if (!isNull) {
487 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->expiration_id, temp.ptr())) {
488 0 : return false;
489 : }
490 : }
491 0 : if (!isNull && !temp->isUndefined()) {
492 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &mExpiration)) {
493 0 : return false;
494 0 : } else if (!mozilla::IsFinite(mExpiration)) {
495 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'expiration' member of DnsCacheEntry");
496 0 : return false;
497 : }
498 : } else {
499 0 : mExpiration = 0.0;
500 : }
501 0 : mIsAnyMemberPresent = true;
502 :
503 0 : if (!isNull) {
504 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->family_id, temp.ptr())) {
505 0 : return false;
506 : }
507 : }
508 0 : if (!isNull && !temp->isUndefined()) {
509 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mFamily)) {
510 0 : return false;
511 : }
512 : } else {
513 : static const char16_t data[] = { 0 };
514 0 : mFamily.Rebind(data, ArrayLength(data) - 1);
515 : }
516 0 : mIsAnyMemberPresent = true;
517 :
518 0 : if (!isNull) {
519 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->hostaddr_id, temp.ptr())) {
520 0 : return false;
521 : }
522 : }
523 0 : if (!isNull && !temp->isUndefined()) {
524 0 : mHostaddr.Construct();
525 0 : if (temp.ref().isObject()) {
526 0 : JS::ForOfIterator iter(cx);
527 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
528 0 : return false;
529 : }
530 0 : if (!iter.valueIsIterable()) {
531 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'hostaddr' member of DnsCacheEntry");
532 0 : return false;
533 : }
534 0 : Sequence<nsString> &arr = (mHostaddr.Value());
535 0 : JS::Rooted<JS::Value> temp(cx);
536 : while (true) {
537 : bool done;
538 0 : if (!iter.next(&temp, &done)) {
539 0 : return false;
540 : }
541 0 : if (done) {
542 0 : break;
543 : }
544 0 : nsString* slotPtr = arr.AppendElement(mozilla::fallible);
545 0 : if (!slotPtr) {
546 0 : JS_ReportOutOfMemory(cx);
547 0 : return false;
548 : }
549 0 : nsString& slot = *slotPtr;
550 0 : if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
551 0 : return false;
552 : }
553 0 : }
554 : } else {
555 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'hostaddr' member of DnsCacheEntry");
556 0 : return false;
557 : }
558 0 : mIsAnyMemberPresent = true;
559 : }
560 :
561 0 : if (!isNull) {
562 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->hostname_id, temp.ptr())) {
563 0 : return false;
564 : }
565 : }
566 0 : if (!isNull && !temp->isUndefined()) {
567 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mHostname)) {
568 0 : return false;
569 : }
570 : } else {
571 : static const char16_t data[] = { 0 };
572 0 : mHostname.Rebind(data, ArrayLength(data) - 1);
573 : }
574 0 : mIsAnyMemberPresent = true;
575 0 : return true;
576 : }
577 :
578 : bool
579 0 : DnsCacheEntry::Init(const nsAString& aJSON)
580 : {
581 0 : AutoJSAPI jsapi;
582 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
583 0 : if (!cleanGlobal) {
584 0 : return false;
585 : }
586 0 : if (!jsapi.Init(cleanGlobal)) {
587 0 : return false;
588 : }
589 0 : JSContext* cx = jsapi.cx();
590 0 : JS::Rooted<JS::Value> json(cx);
591 0 : bool ok = ParseJSON(cx, aJSON, &json);
592 0 : NS_ENSURE_TRUE(ok, false);
593 0 : return Init(cx, json);
594 : }
595 :
596 : bool
597 0 : DnsCacheEntry::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
598 : {
599 0 : DnsCacheEntryAtoms* atomsCache = GetAtomCache<DnsCacheEntryAtoms>(cx);
600 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
601 0 : return false;
602 : }
603 :
604 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
605 0 : if (!obj) {
606 0 : return false;
607 : }
608 0 : rval.set(JS::ObjectValue(*obj));
609 :
610 : do {
611 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
612 0 : JS::Rooted<JS::Value> temp(cx);
613 0 : double const & currentValue = mExpiration;
614 0 : temp.set(JS_NumberValue(double(currentValue)));
615 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->expiration_id, temp, JSPROP_ENUMERATE)) {
616 0 : return false;
617 : }
618 0 : break;
619 : } while(0);
620 :
621 : do {
622 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
623 0 : JS::Rooted<JS::Value> temp(cx);
624 0 : nsString const & currentValue = mFamily;
625 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
626 0 : return false;
627 : }
628 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->family_id, temp, JSPROP_ENUMERATE)) {
629 0 : return false;
630 : }
631 0 : break;
632 : } while(0);
633 :
634 0 : if (mHostaddr.WasPassed()) {
635 : do {
636 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
637 0 : JS::Rooted<JS::Value> temp(cx);
638 0 : Sequence<nsString> const & currentValue = mHostaddr.InternalValue();
639 :
640 0 : uint32_t length = currentValue.Length();
641 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
642 0 : if (!returnArray) {
643 0 : return false;
644 : }
645 : // Scope for 'tmp'
646 : {
647 0 : JS::Rooted<JS::Value> tmp(cx);
648 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
649 : // Control block to let us common up the JS_DefineElement calls when there
650 : // are different ways to succeed at wrapping the object.
651 : do {
652 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue[sequenceIdx0], &tmp)) {
653 0 : return false;
654 : }
655 0 : break;
656 : } while (0);
657 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
658 : JSPROP_ENUMERATE)) {
659 0 : return false;
660 : }
661 : }
662 : }
663 0 : temp.setObject(*returnArray);
664 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->hostaddr_id, temp, JSPROP_ENUMERATE)) {
665 0 : return false;
666 : }
667 0 : break;
668 : } while(0);
669 : }
670 :
671 : do {
672 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
673 0 : JS::Rooted<JS::Value> temp(cx);
674 0 : nsString const & currentValue = mHostname;
675 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
676 0 : return false;
677 : }
678 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->hostname_id, temp, JSPROP_ENUMERATE)) {
679 0 : return false;
680 : }
681 0 : break;
682 : } while(0);
683 :
684 0 : return true;
685 : }
686 :
687 : bool
688 0 : DnsCacheEntry::ToJSON(nsAString& aJSON) const
689 : {
690 0 : AutoJSAPI jsapi;
691 0 : jsapi.Init();
692 0 : JSContext *cx = jsapi.cx();
693 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
694 : // because we'll only be creating objects, in ways that have no
695 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
696 : // which likewise guarantees no side-effects for the sorts of
697 : // things we will pass it.
698 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
699 0 : JS::Rooted<JS::Value> val(cx);
700 0 : if (!ToObjectInternal(cx, &val)) {
701 0 : return false;
702 : }
703 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
704 0 : return StringifyToJSON(cx, obj, aJSON);
705 : }
706 :
707 : void
708 0 : DnsCacheEntry::TraceDictionary(JSTracer* trc)
709 : {
710 0 : }
711 :
712 : DnsCacheEntry&
713 0 : DnsCacheEntry::operator=(const DnsCacheEntry& aOther)
714 : {
715 0 : mExpiration = aOther.mExpiration;
716 0 : mFamily = aOther.mFamily;
717 0 : mHostaddr.Reset();
718 0 : if (aOther.mHostaddr.WasPassed()) {
719 0 : mHostaddr.Construct(aOther.mHostaddr.Value());
720 : }
721 0 : mHostname = aOther.mHostname;
722 0 : return *this;
723 : }
724 :
725 : namespace binding_detail {
726 : } // namespace binding_detail
727 :
728 :
729 :
730 0 : HalfOpenInfoDict::HalfOpenInfoDict()
731 : {
732 : // Safe to pass a null context if we pass a null value
733 0 : Init(nullptr, JS::NullHandleValue);
734 0 : }
735 :
736 :
737 :
738 : bool
739 0 : HalfOpenInfoDict::InitIds(JSContext* cx, HalfOpenInfoDictAtoms* atomsCache)
740 : {
741 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
742 :
743 : // Initialize these in reverse order so that any failure leaves the first one
744 : // uninitialized.
745 0 : if (!atomsCache->speculative_id.init(cx, "speculative")) {
746 0 : return false;
747 : }
748 0 : return true;
749 : }
750 :
751 : bool
752 0 : HalfOpenInfoDict::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
753 : {
754 : // Passing a null JSContext is OK only if we're initing from null,
755 : // Since in that case we will not have to do any property gets
756 : // Also evaluate isNullOrUndefined in order to avoid false-positive
757 : // checkers by static analysis tools
758 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
759 0 : HalfOpenInfoDictAtoms* atomsCache = nullptr;
760 0 : if (cx) {
761 0 : atomsCache = GetAtomCache<HalfOpenInfoDictAtoms>(cx);
762 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
763 0 : return false;
764 : }
765 : }
766 :
767 0 : if (!IsConvertibleToDictionary(val)) {
768 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
769 : }
770 :
771 0 : bool isNull = val.isNullOrUndefined();
772 : // We only need these if !isNull, in which case we have |cx|.
773 0 : Maybe<JS::Rooted<JSObject *> > object;
774 0 : Maybe<JS::Rooted<JS::Value> > temp;
775 0 : if (!isNull) {
776 0 : MOZ_ASSERT(cx);
777 0 : object.emplace(cx, &val.toObject());
778 0 : temp.emplace(cx);
779 : }
780 0 : if (!isNull) {
781 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->speculative_id, temp.ptr())) {
782 0 : return false;
783 : }
784 : }
785 0 : if (!isNull && !temp->isUndefined()) {
786 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mSpeculative)) {
787 0 : return false;
788 : }
789 : } else {
790 0 : mSpeculative = false;
791 : }
792 0 : mIsAnyMemberPresent = true;
793 0 : return true;
794 : }
795 :
796 : bool
797 0 : HalfOpenInfoDict::Init(const nsAString& aJSON)
798 : {
799 0 : AutoJSAPI jsapi;
800 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
801 0 : if (!cleanGlobal) {
802 0 : return false;
803 : }
804 0 : if (!jsapi.Init(cleanGlobal)) {
805 0 : return false;
806 : }
807 0 : JSContext* cx = jsapi.cx();
808 0 : JS::Rooted<JS::Value> json(cx);
809 0 : bool ok = ParseJSON(cx, aJSON, &json);
810 0 : NS_ENSURE_TRUE(ok, false);
811 0 : return Init(cx, json);
812 : }
813 :
814 : bool
815 0 : HalfOpenInfoDict::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
816 : {
817 0 : HalfOpenInfoDictAtoms* atomsCache = GetAtomCache<HalfOpenInfoDictAtoms>(cx);
818 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
819 0 : return false;
820 : }
821 :
822 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
823 0 : if (!obj) {
824 0 : return false;
825 : }
826 0 : rval.set(JS::ObjectValue(*obj));
827 :
828 : do {
829 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
830 0 : JS::Rooted<JS::Value> temp(cx);
831 0 : bool const & currentValue = mSpeculative;
832 0 : temp.setBoolean(currentValue);
833 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->speculative_id, temp, JSPROP_ENUMERATE)) {
834 0 : return false;
835 : }
836 0 : break;
837 : } while(0);
838 :
839 0 : return true;
840 : }
841 :
842 : bool
843 0 : HalfOpenInfoDict::ToJSON(nsAString& aJSON) const
844 : {
845 0 : AutoJSAPI jsapi;
846 0 : jsapi.Init();
847 0 : JSContext *cx = jsapi.cx();
848 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
849 : // because we'll only be creating objects, in ways that have no
850 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
851 : // which likewise guarantees no side-effects for the sorts of
852 : // things we will pass it.
853 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
854 0 : JS::Rooted<JS::Value> val(cx);
855 0 : if (!ToObjectInternal(cx, &val)) {
856 0 : return false;
857 : }
858 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
859 0 : return StringifyToJSON(cx, obj, aJSON);
860 : }
861 :
862 : void
863 0 : HalfOpenInfoDict::TraceDictionary(JSTracer* trc)
864 : {
865 0 : }
866 :
867 : HalfOpenInfoDict&
868 0 : HalfOpenInfoDict::operator=(const HalfOpenInfoDict& aOther)
869 : {
870 0 : mSpeculative = aOther.mSpeculative;
871 0 : return *this;
872 : }
873 :
874 : namespace binding_detail {
875 : } // namespace binding_detail
876 :
877 :
878 :
879 0 : HttpConnInfo::HttpConnInfo()
880 : {
881 : // Safe to pass a null context if we pass a null value
882 0 : Init(nullptr, JS::NullHandleValue);
883 0 : }
884 :
885 :
886 :
887 : bool
888 0 : HttpConnInfo::InitIds(JSContext* cx, HttpConnInfoAtoms* atomsCache)
889 : {
890 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
891 :
892 : // Initialize these in reverse order so that any failure leaves the first one
893 : // uninitialized.
894 0 : if (!atomsCache->ttl_id.init(cx, "ttl") ||
895 0 : !atomsCache->rtt_id.init(cx, "rtt") ||
896 0 : !atomsCache->protocolVersion_id.init(cx, "protocolVersion")) {
897 0 : return false;
898 : }
899 0 : return true;
900 : }
901 :
902 : bool
903 0 : HttpConnInfo::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
904 : {
905 : // Passing a null JSContext is OK only if we're initing from null,
906 : // Since in that case we will not have to do any property gets
907 : // Also evaluate isNullOrUndefined in order to avoid false-positive
908 : // checkers by static analysis tools
909 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
910 0 : HttpConnInfoAtoms* atomsCache = nullptr;
911 0 : if (cx) {
912 0 : atomsCache = GetAtomCache<HttpConnInfoAtoms>(cx);
913 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
914 0 : return false;
915 : }
916 : }
917 :
918 0 : if (!IsConvertibleToDictionary(val)) {
919 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
920 : }
921 :
922 0 : bool isNull = val.isNullOrUndefined();
923 : // We only need these if !isNull, in which case we have |cx|.
924 0 : Maybe<JS::Rooted<JSObject *> > object;
925 0 : Maybe<JS::Rooted<JS::Value> > temp;
926 0 : if (!isNull) {
927 0 : MOZ_ASSERT(cx);
928 0 : object.emplace(cx, &val.toObject());
929 0 : temp.emplace(cx);
930 : }
931 0 : if (!isNull) {
932 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->protocolVersion_id, temp.ptr())) {
933 0 : return false;
934 : }
935 : }
936 0 : if (!isNull && !temp->isUndefined()) {
937 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mProtocolVersion)) {
938 0 : return false;
939 : }
940 : } else {
941 : static const char16_t data[] = { 0 };
942 0 : mProtocolVersion.Rebind(data, ArrayLength(data) - 1);
943 : }
944 0 : mIsAnyMemberPresent = true;
945 :
946 0 : if (!isNull) {
947 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->rtt_id, temp.ptr())) {
948 0 : return false;
949 : }
950 : }
951 0 : if (!isNull && !temp->isUndefined()) {
952 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mRtt)) {
953 0 : return false;
954 : }
955 : } else {
956 0 : mRtt = 0U;
957 : }
958 0 : mIsAnyMemberPresent = true;
959 :
960 0 : if (!isNull) {
961 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->ttl_id, temp.ptr())) {
962 0 : return false;
963 : }
964 : }
965 0 : if (!isNull && !temp->isUndefined()) {
966 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mTtl)) {
967 0 : return false;
968 : }
969 : } else {
970 0 : mTtl = 0U;
971 : }
972 0 : mIsAnyMemberPresent = true;
973 0 : return true;
974 : }
975 :
976 : bool
977 0 : HttpConnInfo::Init(const nsAString& aJSON)
978 : {
979 0 : AutoJSAPI jsapi;
980 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
981 0 : if (!cleanGlobal) {
982 0 : return false;
983 : }
984 0 : if (!jsapi.Init(cleanGlobal)) {
985 0 : return false;
986 : }
987 0 : JSContext* cx = jsapi.cx();
988 0 : JS::Rooted<JS::Value> json(cx);
989 0 : bool ok = ParseJSON(cx, aJSON, &json);
990 0 : NS_ENSURE_TRUE(ok, false);
991 0 : return Init(cx, json);
992 : }
993 :
994 : bool
995 0 : HttpConnInfo::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
996 : {
997 0 : HttpConnInfoAtoms* atomsCache = GetAtomCache<HttpConnInfoAtoms>(cx);
998 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
999 0 : return false;
1000 : }
1001 :
1002 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
1003 0 : if (!obj) {
1004 0 : return false;
1005 : }
1006 0 : rval.set(JS::ObjectValue(*obj));
1007 :
1008 : do {
1009 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1010 0 : JS::Rooted<JS::Value> temp(cx);
1011 0 : nsString const & currentValue = mProtocolVersion;
1012 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1013 0 : return false;
1014 : }
1015 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->protocolVersion_id, temp, JSPROP_ENUMERATE)) {
1016 0 : return false;
1017 : }
1018 0 : break;
1019 : } while(0);
1020 :
1021 : do {
1022 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1023 0 : JS::Rooted<JS::Value> temp(cx);
1024 0 : uint32_t const & currentValue = mRtt;
1025 0 : temp.setNumber(currentValue);
1026 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->rtt_id, temp, JSPROP_ENUMERATE)) {
1027 0 : return false;
1028 : }
1029 0 : break;
1030 : } while(0);
1031 :
1032 : do {
1033 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1034 0 : JS::Rooted<JS::Value> temp(cx);
1035 0 : uint32_t const & currentValue = mTtl;
1036 0 : temp.setNumber(currentValue);
1037 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->ttl_id, temp, JSPROP_ENUMERATE)) {
1038 0 : return false;
1039 : }
1040 0 : break;
1041 : } while(0);
1042 :
1043 0 : return true;
1044 : }
1045 :
1046 : bool
1047 0 : HttpConnInfo::ToJSON(nsAString& aJSON) const
1048 : {
1049 0 : AutoJSAPI jsapi;
1050 0 : jsapi.Init();
1051 0 : JSContext *cx = jsapi.cx();
1052 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1053 : // because we'll only be creating objects, in ways that have no
1054 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1055 : // which likewise guarantees no side-effects for the sorts of
1056 : // things we will pass it.
1057 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
1058 0 : JS::Rooted<JS::Value> val(cx);
1059 0 : if (!ToObjectInternal(cx, &val)) {
1060 0 : return false;
1061 : }
1062 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
1063 0 : return StringifyToJSON(cx, obj, aJSON);
1064 : }
1065 :
1066 : void
1067 0 : HttpConnInfo::TraceDictionary(JSTracer* trc)
1068 : {
1069 0 : }
1070 :
1071 : HttpConnInfo&
1072 0 : HttpConnInfo::operator=(const HttpConnInfo& aOther)
1073 : {
1074 0 : mProtocolVersion = aOther.mProtocolVersion;
1075 0 : mRtt = aOther.mRtt;
1076 0 : mTtl = aOther.mTtl;
1077 0 : return *this;
1078 : }
1079 :
1080 : namespace binding_detail {
1081 : } // namespace binding_detail
1082 :
1083 :
1084 :
1085 0 : RcwnPerfStats::RcwnPerfStats()
1086 : {
1087 : // Safe to pass a null context if we pass a null value
1088 0 : Init(nullptr, JS::NullHandleValue);
1089 0 : }
1090 :
1091 :
1092 :
1093 : bool
1094 0 : RcwnPerfStats::InitIds(JSContext* cx, RcwnPerfStatsAtoms* atomsCache)
1095 : {
1096 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1097 :
1098 : // Initialize these in reverse order so that any failure leaves the first one
1099 : // uninitialized.
1100 0 : if (!atomsCache->stddevLong_id.init(cx, "stddevLong") ||
1101 0 : !atomsCache->avgShort_id.init(cx, "avgShort") ||
1102 0 : !atomsCache->avgLong_id.init(cx, "avgLong")) {
1103 0 : return false;
1104 : }
1105 0 : return true;
1106 : }
1107 :
1108 : bool
1109 0 : RcwnPerfStats::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1110 : {
1111 : // Passing a null JSContext is OK only if we're initing from null,
1112 : // Since in that case we will not have to do any property gets
1113 : // Also evaluate isNullOrUndefined in order to avoid false-positive
1114 : // checkers by static analysis tools
1115 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1116 0 : RcwnPerfStatsAtoms* atomsCache = nullptr;
1117 0 : if (cx) {
1118 0 : atomsCache = GetAtomCache<RcwnPerfStatsAtoms>(cx);
1119 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1120 0 : return false;
1121 : }
1122 : }
1123 :
1124 0 : if (!IsConvertibleToDictionary(val)) {
1125 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
1126 : }
1127 :
1128 0 : bool isNull = val.isNullOrUndefined();
1129 : // We only need these if !isNull, in which case we have |cx|.
1130 0 : Maybe<JS::Rooted<JSObject *> > object;
1131 0 : Maybe<JS::Rooted<JS::Value> > temp;
1132 0 : if (!isNull) {
1133 0 : MOZ_ASSERT(cx);
1134 0 : object.emplace(cx, &val.toObject());
1135 0 : temp.emplace(cx);
1136 : }
1137 0 : if (!isNull) {
1138 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->avgLong_id, temp.ptr())) {
1139 0 : return false;
1140 : }
1141 : }
1142 0 : if (!isNull && !temp->isUndefined()) {
1143 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mAvgLong)) {
1144 0 : return false;
1145 : }
1146 : } else {
1147 0 : mAvgLong = 0U;
1148 : }
1149 0 : mIsAnyMemberPresent = true;
1150 :
1151 0 : if (!isNull) {
1152 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->avgShort_id, temp.ptr())) {
1153 0 : return false;
1154 : }
1155 : }
1156 0 : if (!isNull && !temp->isUndefined()) {
1157 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mAvgShort)) {
1158 0 : return false;
1159 : }
1160 : } else {
1161 0 : mAvgShort = 0U;
1162 : }
1163 0 : mIsAnyMemberPresent = true;
1164 :
1165 0 : if (!isNull) {
1166 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->stddevLong_id, temp.ptr())) {
1167 0 : return false;
1168 : }
1169 : }
1170 0 : if (!isNull && !temp->isUndefined()) {
1171 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mStddevLong)) {
1172 0 : return false;
1173 : }
1174 : } else {
1175 0 : mStddevLong = 0U;
1176 : }
1177 0 : mIsAnyMemberPresent = true;
1178 0 : return true;
1179 : }
1180 :
1181 : bool
1182 0 : RcwnPerfStats::Init(const nsAString& aJSON)
1183 : {
1184 0 : AutoJSAPI jsapi;
1185 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
1186 0 : if (!cleanGlobal) {
1187 0 : return false;
1188 : }
1189 0 : if (!jsapi.Init(cleanGlobal)) {
1190 0 : return false;
1191 : }
1192 0 : JSContext* cx = jsapi.cx();
1193 0 : JS::Rooted<JS::Value> json(cx);
1194 0 : bool ok = ParseJSON(cx, aJSON, &json);
1195 0 : NS_ENSURE_TRUE(ok, false);
1196 0 : return Init(cx, json);
1197 : }
1198 :
1199 : bool
1200 0 : RcwnPerfStats::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1201 : {
1202 0 : RcwnPerfStatsAtoms* atomsCache = GetAtomCache<RcwnPerfStatsAtoms>(cx);
1203 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1204 0 : return false;
1205 : }
1206 :
1207 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
1208 0 : if (!obj) {
1209 0 : return false;
1210 : }
1211 0 : rval.set(JS::ObjectValue(*obj));
1212 :
1213 : do {
1214 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1215 0 : JS::Rooted<JS::Value> temp(cx);
1216 0 : uint32_t const & currentValue = mAvgLong;
1217 0 : temp.setNumber(currentValue);
1218 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->avgLong_id, temp, JSPROP_ENUMERATE)) {
1219 0 : return false;
1220 : }
1221 0 : break;
1222 : } while(0);
1223 :
1224 : do {
1225 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1226 0 : JS::Rooted<JS::Value> temp(cx);
1227 0 : uint32_t const & currentValue = mAvgShort;
1228 0 : temp.setNumber(currentValue);
1229 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->avgShort_id, temp, JSPROP_ENUMERATE)) {
1230 0 : return false;
1231 : }
1232 0 : break;
1233 : } while(0);
1234 :
1235 : do {
1236 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1237 0 : JS::Rooted<JS::Value> temp(cx);
1238 0 : uint32_t const & currentValue = mStddevLong;
1239 0 : temp.setNumber(currentValue);
1240 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->stddevLong_id, temp, JSPROP_ENUMERATE)) {
1241 0 : return false;
1242 : }
1243 0 : break;
1244 : } while(0);
1245 :
1246 0 : return true;
1247 : }
1248 :
1249 : bool
1250 0 : RcwnPerfStats::ToJSON(nsAString& aJSON) const
1251 : {
1252 0 : AutoJSAPI jsapi;
1253 0 : jsapi.Init();
1254 0 : JSContext *cx = jsapi.cx();
1255 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1256 : // because we'll only be creating objects, in ways that have no
1257 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1258 : // which likewise guarantees no side-effects for the sorts of
1259 : // things we will pass it.
1260 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
1261 0 : JS::Rooted<JS::Value> val(cx);
1262 0 : if (!ToObjectInternal(cx, &val)) {
1263 0 : return false;
1264 : }
1265 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
1266 0 : return StringifyToJSON(cx, obj, aJSON);
1267 : }
1268 :
1269 : void
1270 0 : RcwnPerfStats::TraceDictionary(JSTracer* trc)
1271 : {
1272 0 : }
1273 :
1274 : RcwnPerfStats&
1275 0 : RcwnPerfStats::operator=(const RcwnPerfStats& aOther)
1276 : {
1277 0 : mAvgLong = aOther.mAvgLong;
1278 0 : mAvgShort = aOther.mAvgShort;
1279 0 : mStddevLong = aOther.mStddevLong;
1280 0 : return *this;
1281 : }
1282 :
1283 : namespace binding_detail {
1284 : } // namespace binding_detail
1285 :
1286 :
1287 :
1288 0 : SocketElement::SocketElement()
1289 : {
1290 : // Safe to pass a null context if we pass a null value
1291 0 : Init(nullptr, JS::NullHandleValue);
1292 0 : }
1293 :
1294 :
1295 :
1296 : bool
1297 0 : SocketElement::InitIds(JSContext* cx, SocketElementAtoms* atomsCache)
1298 : {
1299 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1300 :
1301 : // Initialize these in reverse order so that any failure leaves the first one
1302 : // uninitialized.
1303 0 : if (!atomsCache->tcp_id.init(cx, "tcp") ||
1304 0 : !atomsCache->sent_id.init(cx, "sent") ||
1305 0 : !atomsCache->received_id.init(cx, "received") ||
1306 0 : !atomsCache->port_id.init(cx, "port") ||
1307 0 : !atomsCache->host_id.init(cx, "host") ||
1308 0 : !atomsCache->active_id.init(cx, "active")) {
1309 0 : return false;
1310 : }
1311 0 : return true;
1312 : }
1313 :
1314 : bool
1315 0 : SocketElement::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1316 : {
1317 : // Passing a null JSContext is OK only if we're initing from null,
1318 : // Since in that case we will not have to do any property gets
1319 : // Also evaluate isNullOrUndefined in order to avoid false-positive
1320 : // checkers by static analysis tools
1321 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1322 0 : SocketElementAtoms* atomsCache = nullptr;
1323 0 : if (cx) {
1324 0 : atomsCache = GetAtomCache<SocketElementAtoms>(cx);
1325 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1326 0 : return false;
1327 : }
1328 : }
1329 :
1330 0 : if (!IsConvertibleToDictionary(val)) {
1331 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
1332 : }
1333 :
1334 0 : bool isNull = val.isNullOrUndefined();
1335 : // We only need these if !isNull, in which case we have |cx|.
1336 0 : Maybe<JS::Rooted<JSObject *> > object;
1337 0 : Maybe<JS::Rooted<JS::Value> > temp;
1338 0 : if (!isNull) {
1339 0 : MOZ_ASSERT(cx);
1340 0 : object.emplace(cx, &val.toObject());
1341 0 : temp.emplace(cx);
1342 : }
1343 0 : if (!isNull) {
1344 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->active_id, temp.ptr())) {
1345 0 : return false;
1346 : }
1347 : }
1348 0 : if (!isNull && !temp->isUndefined()) {
1349 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mActive)) {
1350 0 : return false;
1351 : }
1352 : } else {
1353 0 : mActive = false;
1354 : }
1355 0 : mIsAnyMemberPresent = true;
1356 :
1357 0 : if (!isNull) {
1358 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->host_id, temp.ptr())) {
1359 0 : return false;
1360 : }
1361 : }
1362 0 : if (!isNull && !temp->isUndefined()) {
1363 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mHost)) {
1364 0 : return false;
1365 : }
1366 : } else {
1367 : static const char16_t data[] = { 0 };
1368 0 : mHost.Rebind(data, ArrayLength(data) - 1);
1369 : }
1370 0 : mIsAnyMemberPresent = true;
1371 :
1372 0 : if (!isNull) {
1373 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->port_id, temp.ptr())) {
1374 0 : return false;
1375 : }
1376 : }
1377 0 : if (!isNull && !temp->isUndefined()) {
1378 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mPort)) {
1379 0 : return false;
1380 : }
1381 : } else {
1382 0 : mPort = 0U;
1383 : }
1384 0 : mIsAnyMemberPresent = true;
1385 :
1386 0 : if (!isNull) {
1387 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->received_id, temp.ptr())) {
1388 0 : return false;
1389 : }
1390 : }
1391 0 : if (!isNull && !temp->isUndefined()) {
1392 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &mReceived)) {
1393 0 : return false;
1394 0 : } else if (!mozilla::IsFinite(mReceived)) {
1395 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'received' member of SocketElement");
1396 0 : return false;
1397 : }
1398 : } else {
1399 0 : mReceived = 0.0;
1400 : }
1401 0 : mIsAnyMemberPresent = true;
1402 :
1403 0 : if (!isNull) {
1404 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->sent_id, temp.ptr())) {
1405 0 : return false;
1406 : }
1407 : }
1408 0 : if (!isNull && !temp->isUndefined()) {
1409 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &mSent)) {
1410 0 : return false;
1411 0 : } else if (!mozilla::IsFinite(mSent)) {
1412 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'sent' member of SocketElement");
1413 0 : return false;
1414 : }
1415 : } else {
1416 0 : mSent = 0.0;
1417 : }
1418 0 : mIsAnyMemberPresent = true;
1419 :
1420 0 : if (!isNull) {
1421 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->tcp_id, temp.ptr())) {
1422 0 : return false;
1423 : }
1424 : }
1425 0 : if (!isNull && !temp->isUndefined()) {
1426 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mTcp)) {
1427 0 : return false;
1428 : }
1429 : } else {
1430 0 : mTcp = false;
1431 : }
1432 0 : mIsAnyMemberPresent = true;
1433 0 : return true;
1434 : }
1435 :
1436 : bool
1437 0 : SocketElement::Init(const nsAString& aJSON)
1438 : {
1439 0 : AutoJSAPI jsapi;
1440 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
1441 0 : if (!cleanGlobal) {
1442 0 : return false;
1443 : }
1444 0 : if (!jsapi.Init(cleanGlobal)) {
1445 0 : return false;
1446 : }
1447 0 : JSContext* cx = jsapi.cx();
1448 0 : JS::Rooted<JS::Value> json(cx);
1449 0 : bool ok = ParseJSON(cx, aJSON, &json);
1450 0 : NS_ENSURE_TRUE(ok, false);
1451 0 : return Init(cx, json);
1452 : }
1453 :
1454 : bool
1455 0 : SocketElement::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1456 : {
1457 0 : SocketElementAtoms* atomsCache = GetAtomCache<SocketElementAtoms>(cx);
1458 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1459 0 : return false;
1460 : }
1461 :
1462 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
1463 0 : if (!obj) {
1464 0 : return false;
1465 : }
1466 0 : rval.set(JS::ObjectValue(*obj));
1467 :
1468 : do {
1469 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1470 0 : JS::Rooted<JS::Value> temp(cx);
1471 0 : bool const & currentValue = mActive;
1472 0 : temp.setBoolean(currentValue);
1473 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->active_id, temp, JSPROP_ENUMERATE)) {
1474 0 : return false;
1475 : }
1476 0 : break;
1477 : } while(0);
1478 :
1479 : do {
1480 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1481 0 : JS::Rooted<JS::Value> temp(cx);
1482 0 : nsString const & currentValue = mHost;
1483 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1484 0 : return false;
1485 : }
1486 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->host_id, temp, JSPROP_ENUMERATE)) {
1487 0 : return false;
1488 : }
1489 0 : break;
1490 : } while(0);
1491 :
1492 : do {
1493 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1494 0 : JS::Rooted<JS::Value> temp(cx);
1495 0 : uint32_t const & currentValue = mPort;
1496 0 : temp.setNumber(currentValue);
1497 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->port_id, temp, JSPROP_ENUMERATE)) {
1498 0 : return false;
1499 : }
1500 0 : break;
1501 : } while(0);
1502 :
1503 : do {
1504 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1505 0 : JS::Rooted<JS::Value> temp(cx);
1506 0 : double const & currentValue = mReceived;
1507 0 : temp.set(JS_NumberValue(double(currentValue)));
1508 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->received_id, temp, JSPROP_ENUMERATE)) {
1509 0 : return false;
1510 : }
1511 0 : break;
1512 : } while(0);
1513 :
1514 : do {
1515 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1516 0 : JS::Rooted<JS::Value> temp(cx);
1517 0 : double const & currentValue = mSent;
1518 0 : temp.set(JS_NumberValue(double(currentValue)));
1519 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->sent_id, temp, JSPROP_ENUMERATE)) {
1520 0 : return false;
1521 : }
1522 0 : break;
1523 : } while(0);
1524 :
1525 : do {
1526 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1527 0 : JS::Rooted<JS::Value> temp(cx);
1528 0 : bool const & currentValue = mTcp;
1529 0 : temp.setBoolean(currentValue);
1530 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->tcp_id, temp, JSPROP_ENUMERATE)) {
1531 0 : return false;
1532 : }
1533 0 : break;
1534 : } while(0);
1535 :
1536 0 : return true;
1537 : }
1538 :
1539 : bool
1540 0 : SocketElement::ToJSON(nsAString& aJSON) const
1541 : {
1542 0 : AutoJSAPI jsapi;
1543 0 : jsapi.Init();
1544 0 : JSContext *cx = jsapi.cx();
1545 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1546 : // because we'll only be creating objects, in ways that have no
1547 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1548 : // which likewise guarantees no side-effects for the sorts of
1549 : // things we will pass it.
1550 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
1551 0 : JS::Rooted<JS::Value> val(cx);
1552 0 : if (!ToObjectInternal(cx, &val)) {
1553 0 : return false;
1554 : }
1555 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
1556 0 : return StringifyToJSON(cx, obj, aJSON);
1557 : }
1558 :
1559 : void
1560 0 : SocketElement::TraceDictionary(JSTracer* trc)
1561 : {
1562 0 : }
1563 :
1564 : SocketElement&
1565 0 : SocketElement::operator=(const SocketElement& aOther)
1566 : {
1567 0 : mActive = aOther.mActive;
1568 0 : mHost = aOther.mHost;
1569 0 : mPort = aOther.mPort;
1570 0 : mReceived = aOther.mReceived;
1571 0 : mSent = aOther.mSent;
1572 0 : mTcp = aOther.mTcp;
1573 0 : return *this;
1574 : }
1575 :
1576 : namespace binding_detail {
1577 : } // namespace binding_detail
1578 :
1579 :
1580 :
1581 0 : WebSocketElement::WebSocketElement()
1582 : {
1583 : // Safe to pass a null context if we pass a null value
1584 0 : Init(nullptr, JS::NullHandleValue);
1585 0 : }
1586 :
1587 :
1588 :
1589 : bool
1590 0 : WebSocketElement::InitIds(JSContext* cx, WebSocketElementAtoms* atomsCache)
1591 : {
1592 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1593 :
1594 : // Initialize these in reverse order so that any failure leaves the first one
1595 : // uninitialized.
1596 0 : if (!atomsCache->sentsize_id.init(cx, "sentsize") ||
1597 0 : !atomsCache->receivedsize_id.init(cx, "receivedsize") ||
1598 0 : !atomsCache->msgsent_id.init(cx, "msgsent") ||
1599 0 : !atomsCache->msgreceived_id.init(cx, "msgreceived") ||
1600 0 : !atomsCache->hostport_id.init(cx, "hostport") ||
1601 0 : !atomsCache->encrypted_id.init(cx, "encrypted")) {
1602 0 : return false;
1603 : }
1604 0 : return true;
1605 : }
1606 :
1607 : bool
1608 0 : WebSocketElement::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1609 : {
1610 : // Passing a null JSContext is OK only if we're initing from null,
1611 : // Since in that case we will not have to do any property gets
1612 : // Also evaluate isNullOrUndefined in order to avoid false-positive
1613 : // checkers by static analysis tools
1614 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1615 0 : WebSocketElementAtoms* atomsCache = nullptr;
1616 0 : if (cx) {
1617 0 : atomsCache = GetAtomCache<WebSocketElementAtoms>(cx);
1618 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1619 0 : return false;
1620 : }
1621 : }
1622 :
1623 0 : if (!IsConvertibleToDictionary(val)) {
1624 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
1625 : }
1626 :
1627 0 : bool isNull = val.isNullOrUndefined();
1628 : // We only need these if !isNull, in which case we have |cx|.
1629 0 : Maybe<JS::Rooted<JSObject *> > object;
1630 0 : Maybe<JS::Rooted<JS::Value> > temp;
1631 0 : if (!isNull) {
1632 0 : MOZ_ASSERT(cx);
1633 0 : object.emplace(cx, &val.toObject());
1634 0 : temp.emplace(cx);
1635 : }
1636 0 : if (!isNull) {
1637 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->encrypted_id, temp.ptr())) {
1638 0 : return false;
1639 : }
1640 : }
1641 0 : if (!isNull && !temp->isUndefined()) {
1642 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mEncrypted)) {
1643 0 : return false;
1644 : }
1645 : } else {
1646 0 : mEncrypted = false;
1647 : }
1648 0 : mIsAnyMemberPresent = true;
1649 :
1650 0 : if (!isNull) {
1651 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->hostport_id, temp.ptr())) {
1652 0 : return false;
1653 : }
1654 : }
1655 0 : if (!isNull && !temp->isUndefined()) {
1656 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mHostport)) {
1657 0 : return false;
1658 : }
1659 : } else {
1660 : static const char16_t data[] = { 0 };
1661 0 : mHostport.Rebind(data, ArrayLength(data) - 1);
1662 : }
1663 0 : mIsAnyMemberPresent = true;
1664 :
1665 0 : if (!isNull) {
1666 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->msgreceived_id, temp.ptr())) {
1667 0 : return false;
1668 : }
1669 : }
1670 0 : if (!isNull && !temp->isUndefined()) {
1671 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mMsgreceived)) {
1672 0 : return false;
1673 : }
1674 : } else {
1675 0 : mMsgreceived = 0U;
1676 : }
1677 0 : mIsAnyMemberPresent = true;
1678 :
1679 0 : if (!isNull) {
1680 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->msgsent_id, temp.ptr())) {
1681 0 : return false;
1682 : }
1683 : }
1684 0 : if (!isNull && !temp->isUndefined()) {
1685 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mMsgsent)) {
1686 0 : return false;
1687 : }
1688 : } else {
1689 0 : mMsgsent = 0U;
1690 : }
1691 0 : mIsAnyMemberPresent = true;
1692 :
1693 0 : if (!isNull) {
1694 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->receivedsize_id, temp.ptr())) {
1695 0 : return false;
1696 : }
1697 : }
1698 0 : if (!isNull && !temp->isUndefined()) {
1699 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &mReceivedsize)) {
1700 0 : return false;
1701 0 : } else if (!mozilla::IsFinite(mReceivedsize)) {
1702 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'receivedsize' member of WebSocketElement");
1703 0 : return false;
1704 : }
1705 : } else {
1706 0 : mReceivedsize = 0.0;
1707 : }
1708 0 : mIsAnyMemberPresent = true;
1709 :
1710 0 : if (!isNull) {
1711 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->sentsize_id, temp.ptr())) {
1712 0 : return false;
1713 : }
1714 : }
1715 0 : if (!isNull && !temp->isUndefined()) {
1716 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &mSentsize)) {
1717 0 : return false;
1718 0 : } else if (!mozilla::IsFinite(mSentsize)) {
1719 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'sentsize' member of WebSocketElement");
1720 0 : return false;
1721 : }
1722 : } else {
1723 0 : mSentsize = 0.0;
1724 : }
1725 0 : mIsAnyMemberPresent = true;
1726 0 : return true;
1727 : }
1728 :
1729 : bool
1730 0 : WebSocketElement::Init(const nsAString& aJSON)
1731 : {
1732 0 : AutoJSAPI jsapi;
1733 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
1734 0 : if (!cleanGlobal) {
1735 0 : return false;
1736 : }
1737 0 : if (!jsapi.Init(cleanGlobal)) {
1738 0 : return false;
1739 : }
1740 0 : JSContext* cx = jsapi.cx();
1741 0 : JS::Rooted<JS::Value> json(cx);
1742 0 : bool ok = ParseJSON(cx, aJSON, &json);
1743 0 : NS_ENSURE_TRUE(ok, false);
1744 0 : return Init(cx, json);
1745 : }
1746 :
1747 : bool
1748 0 : WebSocketElement::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1749 : {
1750 0 : WebSocketElementAtoms* atomsCache = GetAtomCache<WebSocketElementAtoms>(cx);
1751 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1752 0 : return false;
1753 : }
1754 :
1755 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
1756 0 : if (!obj) {
1757 0 : return false;
1758 : }
1759 0 : rval.set(JS::ObjectValue(*obj));
1760 :
1761 : do {
1762 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1763 0 : JS::Rooted<JS::Value> temp(cx);
1764 0 : bool const & currentValue = mEncrypted;
1765 0 : temp.setBoolean(currentValue);
1766 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->encrypted_id, temp, JSPROP_ENUMERATE)) {
1767 0 : return false;
1768 : }
1769 0 : break;
1770 : } while(0);
1771 :
1772 : do {
1773 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1774 0 : JS::Rooted<JS::Value> temp(cx);
1775 0 : nsString const & currentValue = mHostport;
1776 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1777 0 : return false;
1778 : }
1779 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->hostport_id, temp, JSPROP_ENUMERATE)) {
1780 0 : return false;
1781 : }
1782 0 : break;
1783 : } while(0);
1784 :
1785 : do {
1786 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1787 0 : JS::Rooted<JS::Value> temp(cx);
1788 0 : uint32_t const & currentValue = mMsgreceived;
1789 0 : temp.setNumber(currentValue);
1790 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->msgreceived_id, temp, JSPROP_ENUMERATE)) {
1791 0 : return false;
1792 : }
1793 0 : break;
1794 : } while(0);
1795 :
1796 : do {
1797 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1798 0 : JS::Rooted<JS::Value> temp(cx);
1799 0 : uint32_t const & currentValue = mMsgsent;
1800 0 : temp.setNumber(currentValue);
1801 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->msgsent_id, temp, JSPROP_ENUMERATE)) {
1802 0 : return false;
1803 : }
1804 0 : break;
1805 : } while(0);
1806 :
1807 : do {
1808 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1809 0 : JS::Rooted<JS::Value> temp(cx);
1810 0 : double const & currentValue = mReceivedsize;
1811 0 : temp.set(JS_NumberValue(double(currentValue)));
1812 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->receivedsize_id, temp, JSPROP_ENUMERATE)) {
1813 0 : return false;
1814 : }
1815 0 : break;
1816 : } while(0);
1817 :
1818 : do {
1819 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1820 0 : JS::Rooted<JS::Value> temp(cx);
1821 0 : double const & currentValue = mSentsize;
1822 0 : temp.set(JS_NumberValue(double(currentValue)));
1823 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->sentsize_id, temp, JSPROP_ENUMERATE)) {
1824 0 : return false;
1825 : }
1826 0 : break;
1827 : } while(0);
1828 :
1829 0 : return true;
1830 : }
1831 :
1832 : bool
1833 0 : WebSocketElement::ToJSON(nsAString& aJSON) const
1834 : {
1835 0 : AutoJSAPI jsapi;
1836 0 : jsapi.Init();
1837 0 : JSContext *cx = jsapi.cx();
1838 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1839 : // because we'll only be creating objects, in ways that have no
1840 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1841 : // which likewise guarantees no side-effects for the sorts of
1842 : // things we will pass it.
1843 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
1844 0 : JS::Rooted<JS::Value> val(cx);
1845 0 : if (!ToObjectInternal(cx, &val)) {
1846 0 : return false;
1847 : }
1848 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
1849 0 : return StringifyToJSON(cx, obj, aJSON);
1850 : }
1851 :
1852 : void
1853 0 : WebSocketElement::TraceDictionary(JSTracer* trc)
1854 : {
1855 0 : }
1856 :
1857 : WebSocketElement&
1858 0 : WebSocketElement::operator=(const WebSocketElement& aOther)
1859 : {
1860 0 : mEncrypted = aOther.mEncrypted;
1861 0 : mHostport = aOther.mHostport;
1862 0 : mMsgreceived = aOther.mMsgreceived;
1863 0 : mMsgsent = aOther.mMsgsent;
1864 0 : mReceivedsize = aOther.mReceivedsize;
1865 0 : mSentsize = aOther.mSentsize;
1866 0 : return *this;
1867 : }
1868 :
1869 : namespace binding_detail {
1870 : } // namespace binding_detail
1871 :
1872 :
1873 :
1874 0 : DNSCacheDict::DNSCacheDict()
1875 : {
1876 : // Safe to pass a null context if we pass a null value
1877 0 : Init(nullptr, JS::NullHandleValue);
1878 0 : }
1879 :
1880 :
1881 :
1882 : bool
1883 0 : DNSCacheDict::InitIds(JSContext* cx, DNSCacheDictAtoms* atomsCache)
1884 : {
1885 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1886 :
1887 : // Initialize these in reverse order so that any failure leaves the first one
1888 : // uninitialized.
1889 0 : if (!atomsCache->entries_id.init(cx, "entries")) {
1890 0 : return false;
1891 : }
1892 0 : return true;
1893 : }
1894 :
1895 : bool
1896 0 : DNSCacheDict::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1897 : {
1898 : // Passing a null JSContext is OK only if we're initing from null,
1899 : // Since in that case we will not have to do any property gets
1900 : // Also evaluate isNullOrUndefined in order to avoid false-positive
1901 : // checkers by static analysis tools
1902 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1903 0 : DNSCacheDictAtoms* atomsCache = nullptr;
1904 0 : if (cx) {
1905 0 : atomsCache = GetAtomCache<DNSCacheDictAtoms>(cx);
1906 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1907 0 : return false;
1908 : }
1909 : }
1910 :
1911 0 : if (!IsConvertibleToDictionary(val)) {
1912 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
1913 : }
1914 :
1915 0 : bool isNull = val.isNullOrUndefined();
1916 : // We only need these if !isNull, in which case we have |cx|.
1917 0 : Maybe<JS::Rooted<JSObject *> > object;
1918 0 : Maybe<JS::Rooted<JS::Value> > temp;
1919 0 : if (!isNull) {
1920 0 : MOZ_ASSERT(cx);
1921 0 : object.emplace(cx, &val.toObject());
1922 0 : temp.emplace(cx);
1923 : }
1924 0 : if (!isNull) {
1925 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->entries_id, temp.ptr())) {
1926 0 : return false;
1927 : }
1928 : }
1929 0 : if (!isNull && !temp->isUndefined()) {
1930 0 : mEntries.Construct();
1931 0 : if (temp.ref().isObject()) {
1932 0 : JS::ForOfIterator iter(cx);
1933 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
1934 0 : return false;
1935 : }
1936 0 : if (!iter.valueIsIterable()) {
1937 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'entries' member of DNSCacheDict");
1938 0 : return false;
1939 : }
1940 0 : Sequence<DnsCacheEntry> &arr = (mEntries.Value());
1941 0 : JS::Rooted<JS::Value> temp(cx);
1942 : while (true) {
1943 : bool done;
1944 0 : if (!iter.next(&temp, &done)) {
1945 0 : return false;
1946 : }
1947 0 : if (done) {
1948 0 : break;
1949 : }
1950 0 : DnsCacheEntry* slotPtr = arr.AppendElement(mozilla::fallible);
1951 0 : if (!slotPtr) {
1952 0 : JS_ReportOutOfMemory(cx);
1953 0 : return false;
1954 : }
1955 0 : DnsCacheEntry& slot = *slotPtr;
1956 0 : if (!slot.Init(cx, temp, "Element of 'entries' member of DNSCacheDict", passedToJSImpl)) {
1957 0 : return false;
1958 : }
1959 0 : }
1960 : } else {
1961 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'entries' member of DNSCacheDict");
1962 0 : return false;
1963 : }
1964 0 : mIsAnyMemberPresent = true;
1965 : }
1966 0 : return true;
1967 : }
1968 :
1969 : bool
1970 0 : DNSCacheDict::Init(const nsAString& aJSON)
1971 : {
1972 0 : AutoJSAPI jsapi;
1973 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
1974 0 : if (!cleanGlobal) {
1975 0 : return false;
1976 : }
1977 0 : if (!jsapi.Init(cleanGlobal)) {
1978 0 : return false;
1979 : }
1980 0 : JSContext* cx = jsapi.cx();
1981 0 : JS::Rooted<JS::Value> json(cx);
1982 0 : bool ok = ParseJSON(cx, aJSON, &json);
1983 0 : NS_ENSURE_TRUE(ok, false);
1984 0 : return Init(cx, json);
1985 : }
1986 :
1987 : bool
1988 0 : DNSCacheDict::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1989 : {
1990 0 : DNSCacheDictAtoms* atomsCache = GetAtomCache<DNSCacheDictAtoms>(cx);
1991 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1992 0 : return false;
1993 : }
1994 :
1995 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
1996 0 : if (!obj) {
1997 0 : return false;
1998 : }
1999 0 : rval.set(JS::ObjectValue(*obj));
2000 :
2001 0 : if (mEntries.WasPassed()) {
2002 : do {
2003 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2004 0 : JS::Rooted<JS::Value> temp(cx);
2005 0 : Sequence<DnsCacheEntry> const & currentValue = mEntries.InternalValue();
2006 :
2007 0 : uint32_t length = currentValue.Length();
2008 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
2009 0 : if (!returnArray) {
2010 0 : return false;
2011 : }
2012 : // Scope for 'tmp'
2013 : {
2014 0 : JS::Rooted<JS::Value> tmp(cx);
2015 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
2016 : // Control block to let us common up the JS_DefineElement calls when there
2017 : // are different ways to succeed at wrapping the object.
2018 : do {
2019 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
2020 0 : return false;
2021 : }
2022 0 : break;
2023 : } while (0);
2024 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
2025 : JSPROP_ENUMERATE)) {
2026 0 : return false;
2027 : }
2028 : }
2029 : }
2030 0 : temp.setObject(*returnArray);
2031 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->entries_id, temp, JSPROP_ENUMERATE)) {
2032 0 : return false;
2033 : }
2034 0 : break;
2035 : } while(0);
2036 : }
2037 :
2038 0 : return true;
2039 : }
2040 :
2041 : bool
2042 0 : DNSCacheDict::ToJSON(nsAString& aJSON) const
2043 : {
2044 0 : AutoJSAPI jsapi;
2045 0 : jsapi.Init();
2046 0 : JSContext *cx = jsapi.cx();
2047 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
2048 : // because we'll only be creating objects, in ways that have no
2049 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
2050 : // which likewise guarantees no side-effects for the sorts of
2051 : // things we will pass it.
2052 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
2053 0 : JS::Rooted<JS::Value> val(cx);
2054 0 : if (!ToObjectInternal(cx, &val)) {
2055 0 : return false;
2056 : }
2057 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
2058 0 : return StringifyToJSON(cx, obj, aJSON);
2059 : }
2060 :
2061 : void
2062 0 : DNSCacheDict::TraceDictionary(JSTracer* trc)
2063 : {
2064 0 : }
2065 :
2066 : DNSCacheDict&
2067 0 : DNSCacheDict::operator=(const DNSCacheDict& aOther)
2068 : {
2069 0 : mEntries.Reset();
2070 0 : if (aOther.mEntries.WasPassed()) {
2071 0 : mEntries.Construct(aOther.mEntries.Value());
2072 : }
2073 0 : return *this;
2074 : }
2075 :
2076 : namespace binding_detail {
2077 : } // namespace binding_detail
2078 :
2079 :
2080 :
2081 0 : HttpConnectionElement::HttpConnectionElement()
2082 : {
2083 : // Safe to pass a null context if we pass a null value
2084 0 : Init(nullptr, JS::NullHandleValue);
2085 0 : }
2086 :
2087 :
2088 :
2089 : bool
2090 0 : HttpConnectionElement::InitIds(JSContext* cx, HttpConnectionElementAtoms* atomsCache)
2091 : {
2092 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
2093 :
2094 : // Initialize these in reverse order so that any failure leaves the first one
2095 : // uninitialized.
2096 0 : if (!atomsCache->ssl_id.init(cx, "ssl") ||
2097 0 : !atomsCache->spdy_id.init(cx, "spdy") ||
2098 0 : !atomsCache->port_id.init(cx, "port") ||
2099 0 : !atomsCache->idle_id.init(cx, "idle") ||
2100 0 : !atomsCache->host_id.init(cx, "host") ||
2101 0 : !atomsCache->halfOpens_id.init(cx, "halfOpens") ||
2102 0 : !atomsCache->active_id.init(cx, "active")) {
2103 0 : return false;
2104 : }
2105 0 : return true;
2106 : }
2107 :
2108 : bool
2109 0 : HttpConnectionElement::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
2110 : {
2111 : // Passing a null JSContext is OK only if we're initing from null,
2112 : // Since in that case we will not have to do any property gets
2113 : // Also evaluate isNullOrUndefined in order to avoid false-positive
2114 : // checkers by static analysis tools
2115 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
2116 0 : HttpConnectionElementAtoms* atomsCache = nullptr;
2117 0 : if (cx) {
2118 0 : atomsCache = GetAtomCache<HttpConnectionElementAtoms>(cx);
2119 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2120 0 : return false;
2121 : }
2122 : }
2123 :
2124 0 : if (!IsConvertibleToDictionary(val)) {
2125 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
2126 : }
2127 :
2128 0 : bool isNull = val.isNullOrUndefined();
2129 : // We only need these if !isNull, in which case we have |cx|.
2130 0 : Maybe<JS::Rooted<JSObject *> > object;
2131 0 : Maybe<JS::Rooted<JS::Value> > temp;
2132 0 : if (!isNull) {
2133 0 : MOZ_ASSERT(cx);
2134 0 : object.emplace(cx, &val.toObject());
2135 0 : temp.emplace(cx);
2136 : }
2137 0 : if (!isNull) {
2138 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->active_id, temp.ptr())) {
2139 0 : return false;
2140 : }
2141 : }
2142 0 : if (!isNull && !temp->isUndefined()) {
2143 0 : mActive.Construct();
2144 0 : if (temp.ref().isObject()) {
2145 0 : JS::ForOfIterator iter(cx);
2146 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
2147 0 : return false;
2148 : }
2149 0 : if (!iter.valueIsIterable()) {
2150 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'active' member of HttpConnectionElement");
2151 0 : return false;
2152 : }
2153 0 : Sequence<HttpConnInfo> &arr = (mActive.Value());
2154 0 : JS::Rooted<JS::Value> temp(cx);
2155 : while (true) {
2156 : bool done;
2157 0 : if (!iter.next(&temp, &done)) {
2158 0 : return false;
2159 : }
2160 0 : if (done) {
2161 0 : break;
2162 : }
2163 0 : HttpConnInfo* slotPtr = arr.AppendElement(mozilla::fallible);
2164 0 : if (!slotPtr) {
2165 0 : JS_ReportOutOfMemory(cx);
2166 0 : return false;
2167 : }
2168 0 : HttpConnInfo& slot = *slotPtr;
2169 0 : if (!slot.Init(cx, temp, "Element of 'active' member of HttpConnectionElement", passedToJSImpl)) {
2170 0 : return false;
2171 : }
2172 0 : }
2173 : } else {
2174 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'active' member of HttpConnectionElement");
2175 0 : return false;
2176 : }
2177 0 : mIsAnyMemberPresent = true;
2178 : }
2179 :
2180 0 : if (!isNull) {
2181 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->halfOpens_id, temp.ptr())) {
2182 0 : return false;
2183 : }
2184 : }
2185 0 : if (!isNull && !temp->isUndefined()) {
2186 0 : mHalfOpens.Construct();
2187 0 : if (temp.ref().isObject()) {
2188 0 : JS::ForOfIterator iter(cx);
2189 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
2190 0 : return false;
2191 : }
2192 0 : if (!iter.valueIsIterable()) {
2193 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'halfOpens' member of HttpConnectionElement");
2194 0 : return false;
2195 : }
2196 0 : Sequence<HalfOpenInfoDict> &arr = (mHalfOpens.Value());
2197 0 : JS::Rooted<JS::Value> temp(cx);
2198 : while (true) {
2199 : bool done;
2200 0 : if (!iter.next(&temp, &done)) {
2201 0 : return false;
2202 : }
2203 0 : if (done) {
2204 0 : break;
2205 : }
2206 0 : HalfOpenInfoDict* slotPtr = arr.AppendElement(mozilla::fallible);
2207 0 : if (!slotPtr) {
2208 0 : JS_ReportOutOfMemory(cx);
2209 0 : return false;
2210 : }
2211 0 : HalfOpenInfoDict& slot = *slotPtr;
2212 0 : if (!slot.Init(cx, temp, "Element of 'halfOpens' member of HttpConnectionElement", passedToJSImpl)) {
2213 0 : return false;
2214 : }
2215 0 : }
2216 : } else {
2217 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'halfOpens' member of HttpConnectionElement");
2218 0 : return false;
2219 : }
2220 0 : mIsAnyMemberPresent = true;
2221 : }
2222 :
2223 0 : if (!isNull) {
2224 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->host_id, temp.ptr())) {
2225 0 : return false;
2226 : }
2227 : }
2228 0 : if (!isNull && !temp->isUndefined()) {
2229 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mHost)) {
2230 0 : return false;
2231 : }
2232 : } else {
2233 : static const char16_t data[] = { 0 };
2234 0 : mHost.Rebind(data, ArrayLength(data) - 1);
2235 : }
2236 0 : mIsAnyMemberPresent = true;
2237 :
2238 0 : if (!isNull) {
2239 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->idle_id, temp.ptr())) {
2240 0 : return false;
2241 : }
2242 : }
2243 0 : if (!isNull && !temp->isUndefined()) {
2244 0 : mIdle.Construct();
2245 0 : if (temp.ref().isObject()) {
2246 0 : JS::ForOfIterator iter(cx);
2247 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
2248 0 : return false;
2249 : }
2250 0 : if (!iter.valueIsIterable()) {
2251 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'idle' member of HttpConnectionElement");
2252 0 : return false;
2253 : }
2254 0 : Sequence<HttpConnInfo> &arr = (mIdle.Value());
2255 0 : JS::Rooted<JS::Value> temp(cx);
2256 : while (true) {
2257 : bool done;
2258 0 : if (!iter.next(&temp, &done)) {
2259 0 : return false;
2260 : }
2261 0 : if (done) {
2262 0 : break;
2263 : }
2264 0 : HttpConnInfo* slotPtr = arr.AppendElement(mozilla::fallible);
2265 0 : if (!slotPtr) {
2266 0 : JS_ReportOutOfMemory(cx);
2267 0 : return false;
2268 : }
2269 0 : HttpConnInfo& slot = *slotPtr;
2270 0 : if (!slot.Init(cx, temp, "Element of 'idle' member of HttpConnectionElement", passedToJSImpl)) {
2271 0 : return false;
2272 : }
2273 0 : }
2274 : } else {
2275 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'idle' member of HttpConnectionElement");
2276 0 : return false;
2277 : }
2278 0 : mIsAnyMemberPresent = true;
2279 : }
2280 :
2281 0 : if (!isNull) {
2282 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->port_id, temp.ptr())) {
2283 0 : return false;
2284 : }
2285 : }
2286 0 : if (!isNull && !temp->isUndefined()) {
2287 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mPort)) {
2288 0 : return false;
2289 : }
2290 : } else {
2291 0 : mPort = 0U;
2292 : }
2293 0 : mIsAnyMemberPresent = true;
2294 :
2295 0 : if (!isNull) {
2296 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->spdy_id, temp.ptr())) {
2297 0 : return false;
2298 : }
2299 : }
2300 0 : if (!isNull && !temp->isUndefined()) {
2301 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mSpdy)) {
2302 0 : return false;
2303 : }
2304 : } else {
2305 0 : mSpdy = false;
2306 : }
2307 0 : mIsAnyMemberPresent = true;
2308 :
2309 0 : if (!isNull) {
2310 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->ssl_id, temp.ptr())) {
2311 0 : return false;
2312 : }
2313 : }
2314 0 : if (!isNull && !temp->isUndefined()) {
2315 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mSsl)) {
2316 0 : return false;
2317 : }
2318 : } else {
2319 0 : mSsl = false;
2320 : }
2321 0 : mIsAnyMemberPresent = true;
2322 0 : return true;
2323 : }
2324 :
2325 : bool
2326 0 : HttpConnectionElement::Init(const nsAString& aJSON)
2327 : {
2328 0 : AutoJSAPI jsapi;
2329 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
2330 0 : if (!cleanGlobal) {
2331 0 : return false;
2332 : }
2333 0 : if (!jsapi.Init(cleanGlobal)) {
2334 0 : return false;
2335 : }
2336 0 : JSContext* cx = jsapi.cx();
2337 0 : JS::Rooted<JS::Value> json(cx);
2338 0 : bool ok = ParseJSON(cx, aJSON, &json);
2339 0 : NS_ENSURE_TRUE(ok, false);
2340 0 : return Init(cx, json);
2341 : }
2342 :
2343 : bool
2344 0 : HttpConnectionElement::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
2345 : {
2346 0 : HttpConnectionElementAtoms* atomsCache = GetAtomCache<HttpConnectionElementAtoms>(cx);
2347 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2348 0 : return false;
2349 : }
2350 :
2351 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
2352 0 : if (!obj) {
2353 0 : return false;
2354 : }
2355 0 : rval.set(JS::ObjectValue(*obj));
2356 :
2357 0 : if (mActive.WasPassed()) {
2358 : do {
2359 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2360 0 : JS::Rooted<JS::Value> temp(cx);
2361 0 : Sequence<HttpConnInfo> const & currentValue = mActive.InternalValue();
2362 :
2363 0 : uint32_t length = currentValue.Length();
2364 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
2365 0 : if (!returnArray) {
2366 0 : return false;
2367 : }
2368 : // Scope for 'tmp'
2369 : {
2370 0 : JS::Rooted<JS::Value> tmp(cx);
2371 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
2372 : // Control block to let us common up the JS_DefineElement calls when there
2373 : // are different ways to succeed at wrapping the object.
2374 : do {
2375 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
2376 0 : return false;
2377 : }
2378 0 : break;
2379 : } while (0);
2380 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
2381 : JSPROP_ENUMERATE)) {
2382 0 : return false;
2383 : }
2384 : }
2385 : }
2386 0 : temp.setObject(*returnArray);
2387 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->active_id, temp, JSPROP_ENUMERATE)) {
2388 0 : return false;
2389 : }
2390 0 : break;
2391 : } while(0);
2392 : }
2393 :
2394 0 : if (mHalfOpens.WasPassed()) {
2395 : do {
2396 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2397 0 : JS::Rooted<JS::Value> temp(cx);
2398 0 : Sequence<HalfOpenInfoDict> const & currentValue = mHalfOpens.InternalValue();
2399 :
2400 0 : uint32_t length = currentValue.Length();
2401 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
2402 0 : if (!returnArray) {
2403 0 : return false;
2404 : }
2405 : // Scope for 'tmp'
2406 : {
2407 0 : JS::Rooted<JS::Value> tmp(cx);
2408 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
2409 : // Control block to let us common up the JS_DefineElement calls when there
2410 : // are different ways to succeed at wrapping the object.
2411 : do {
2412 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
2413 0 : return false;
2414 : }
2415 0 : break;
2416 : } while (0);
2417 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
2418 : JSPROP_ENUMERATE)) {
2419 0 : return false;
2420 : }
2421 : }
2422 : }
2423 0 : temp.setObject(*returnArray);
2424 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->halfOpens_id, temp, JSPROP_ENUMERATE)) {
2425 0 : return false;
2426 : }
2427 0 : break;
2428 : } while(0);
2429 : }
2430 :
2431 : do {
2432 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2433 0 : JS::Rooted<JS::Value> temp(cx);
2434 0 : nsString const & currentValue = mHost;
2435 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
2436 0 : return false;
2437 : }
2438 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->host_id, temp, JSPROP_ENUMERATE)) {
2439 0 : return false;
2440 : }
2441 0 : break;
2442 : } while(0);
2443 :
2444 0 : if (mIdle.WasPassed()) {
2445 : do {
2446 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2447 0 : JS::Rooted<JS::Value> temp(cx);
2448 0 : Sequence<HttpConnInfo> const & currentValue = mIdle.InternalValue();
2449 :
2450 0 : uint32_t length = currentValue.Length();
2451 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
2452 0 : if (!returnArray) {
2453 0 : return false;
2454 : }
2455 : // Scope for 'tmp'
2456 : {
2457 0 : JS::Rooted<JS::Value> tmp(cx);
2458 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
2459 : // Control block to let us common up the JS_DefineElement calls when there
2460 : // are different ways to succeed at wrapping the object.
2461 : do {
2462 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
2463 0 : return false;
2464 : }
2465 0 : break;
2466 : } while (0);
2467 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
2468 : JSPROP_ENUMERATE)) {
2469 0 : return false;
2470 : }
2471 : }
2472 : }
2473 0 : temp.setObject(*returnArray);
2474 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->idle_id, temp, JSPROP_ENUMERATE)) {
2475 0 : return false;
2476 : }
2477 0 : break;
2478 : } while(0);
2479 : }
2480 :
2481 : do {
2482 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2483 0 : JS::Rooted<JS::Value> temp(cx);
2484 0 : uint32_t const & currentValue = mPort;
2485 0 : temp.setNumber(currentValue);
2486 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->port_id, temp, JSPROP_ENUMERATE)) {
2487 0 : return false;
2488 : }
2489 0 : break;
2490 : } while(0);
2491 :
2492 : do {
2493 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2494 0 : JS::Rooted<JS::Value> temp(cx);
2495 0 : bool const & currentValue = mSpdy;
2496 0 : temp.setBoolean(currentValue);
2497 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->spdy_id, temp, JSPROP_ENUMERATE)) {
2498 0 : return false;
2499 : }
2500 0 : break;
2501 : } while(0);
2502 :
2503 : do {
2504 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2505 0 : JS::Rooted<JS::Value> temp(cx);
2506 0 : bool const & currentValue = mSsl;
2507 0 : temp.setBoolean(currentValue);
2508 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->ssl_id, temp, JSPROP_ENUMERATE)) {
2509 0 : return false;
2510 : }
2511 0 : break;
2512 : } while(0);
2513 :
2514 0 : return true;
2515 : }
2516 :
2517 : bool
2518 0 : HttpConnectionElement::ToJSON(nsAString& aJSON) const
2519 : {
2520 0 : AutoJSAPI jsapi;
2521 0 : jsapi.Init();
2522 0 : JSContext *cx = jsapi.cx();
2523 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
2524 : // because we'll only be creating objects, in ways that have no
2525 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
2526 : // which likewise guarantees no side-effects for the sorts of
2527 : // things we will pass it.
2528 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
2529 0 : JS::Rooted<JS::Value> val(cx);
2530 0 : if (!ToObjectInternal(cx, &val)) {
2531 0 : return false;
2532 : }
2533 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
2534 0 : return StringifyToJSON(cx, obj, aJSON);
2535 : }
2536 :
2537 : void
2538 0 : HttpConnectionElement::TraceDictionary(JSTracer* trc)
2539 : {
2540 0 : }
2541 :
2542 : HttpConnectionElement&
2543 0 : HttpConnectionElement::operator=(const HttpConnectionElement& aOther)
2544 : {
2545 0 : mActive.Reset();
2546 0 : if (aOther.mActive.WasPassed()) {
2547 0 : mActive.Construct(aOther.mActive.Value());
2548 : }
2549 0 : mHalfOpens.Reset();
2550 0 : if (aOther.mHalfOpens.WasPassed()) {
2551 0 : mHalfOpens.Construct(aOther.mHalfOpens.Value());
2552 : }
2553 0 : mHost = aOther.mHost;
2554 0 : mIdle.Reset();
2555 0 : if (aOther.mIdle.WasPassed()) {
2556 0 : mIdle.Construct(aOther.mIdle.Value());
2557 : }
2558 0 : mPort = aOther.mPort;
2559 0 : mSpdy = aOther.mSpdy;
2560 0 : mSsl = aOther.mSsl;
2561 0 : return *this;
2562 : }
2563 :
2564 : namespace binding_detail {
2565 : } // namespace binding_detail
2566 :
2567 :
2568 :
2569 0 : RcwnStatus::RcwnStatus()
2570 : {
2571 : // Safe to pass a null context if we pass a null value
2572 0 : Init(nullptr, JS::NullHandleValue);
2573 0 : }
2574 :
2575 :
2576 :
2577 : bool
2578 0 : RcwnStatus::InitIds(JSContext* cx, RcwnStatusAtoms* atomsCache)
2579 : {
2580 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
2581 :
2582 : // Initialize these in reverse order so that any failure leaves the first one
2583 : // uninitialized.
2584 0 : if (!atomsCache->totalNetworkRequests_id.init(cx, "totalNetworkRequests") ||
2585 0 : !atomsCache->rcwnNetWonCount_id.init(cx, "rcwnNetWonCount") ||
2586 0 : !atomsCache->rcwnCacheWonCount_id.init(cx, "rcwnCacheWonCount") ||
2587 0 : !atomsCache->perfStats_id.init(cx, "perfStats") ||
2588 0 : !atomsCache->cacheSlowCount_id.init(cx, "cacheSlowCount") ||
2589 0 : !atomsCache->cacheNotSlowCount_id.init(cx, "cacheNotSlowCount")) {
2590 0 : return false;
2591 : }
2592 0 : return true;
2593 : }
2594 :
2595 : bool
2596 0 : RcwnStatus::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
2597 : {
2598 : // Passing a null JSContext is OK only if we're initing from null,
2599 : // Since in that case we will not have to do any property gets
2600 : // Also evaluate isNullOrUndefined in order to avoid false-positive
2601 : // checkers by static analysis tools
2602 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
2603 0 : RcwnStatusAtoms* atomsCache = nullptr;
2604 0 : if (cx) {
2605 0 : atomsCache = GetAtomCache<RcwnStatusAtoms>(cx);
2606 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2607 0 : return false;
2608 : }
2609 : }
2610 :
2611 0 : if (!IsConvertibleToDictionary(val)) {
2612 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
2613 : }
2614 :
2615 0 : bool isNull = val.isNullOrUndefined();
2616 : // We only need these if !isNull, in which case we have |cx|.
2617 0 : Maybe<JS::Rooted<JSObject *> > object;
2618 0 : Maybe<JS::Rooted<JS::Value> > temp;
2619 0 : if (!isNull) {
2620 0 : MOZ_ASSERT(cx);
2621 0 : object.emplace(cx, &val.toObject());
2622 0 : temp.emplace(cx);
2623 : }
2624 0 : if (!isNull) {
2625 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->cacheNotSlowCount_id, temp.ptr())) {
2626 0 : return false;
2627 : }
2628 : }
2629 0 : if (!isNull && !temp->isUndefined()) {
2630 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mCacheNotSlowCount)) {
2631 0 : return false;
2632 : }
2633 : } else {
2634 0 : mCacheNotSlowCount = 0U;
2635 : }
2636 0 : mIsAnyMemberPresent = true;
2637 :
2638 0 : if (!isNull) {
2639 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->cacheSlowCount_id, temp.ptr())) {
2640 0 : return false;
2641 : }
2642 : }
2643 0 : if (!isNull && !temp->isUndefined()) {
2644 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mCacheSlowCount)) {
2645 0 : return false;
2646 : }
2647 : } else {
2648 0 : mCacheSlowCount = 0U;
2649 : }
2650 0 : mIsAnyMemberPresent = true;
2651 :
2652 0 : if (!isNull) {
2653 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->perfStats_id, temp.ptr())) {
2654 0 : return false;
2655 : }
2656 : }
2657 0 : if (!isNull && !temp->isUndefined()) {
2658 0 : mPerfStats.Construct();
2659 0 : if (temp.ref().isObject()) {
2660 0 : JS::ForOfIterator iter(cx);
2661 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
2662 0 : return false;
2663 : }
2664 0 : if (!iter.valueIsIterable()) {
2665 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'perfStats' member of RcwnStatus");
2666 0 : return false;
2667 : }
2668 0 : Sequence<RcwnPerfStats> &arr = (mPerfStats.Value());
2669 0 : JS::Rooted<JS::Value> temp(cx);
2670 : while (true) {
2671 : bool done;
2672 0 : if (!iter.next(&temp, &done)) {
2673 0 : return false;
2674 : }
2675 0 : if (done) {
2676 0 : break;
2677 : }
2678 0 : RcwnPerfStats* slotPtr = arr.AppendElement(mozilla::fallible);
2679 0 : if (!slotPtr) {
2680 0 : JS_ReportOutOfMemory(cx);
2681 0 : return false;
2682 : }
2683 0 : RcwnPerfStats& slot = *slotPtr;
2684 0 : if (!slot.Init(cx, temp, "Element of 'perfStats' member of RcwnStatus", passedToJSImpl)) {
2685 0 : return false;
2686 : }
2687 0 : }
2688 : } else {
2689 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'perfStats' member of RcwnStatus");
2690 0 : return false;
2691 : }
2692 0 : mIsAnyMemberPresent = true;
2693 : }
2694 :
2695 0 : if (!isNull) {
2696 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->rcwnCacheWonCount_id, temp.ptr())) {
2697 0 : return false;
2698 : }
2699 : }
2700 0 : if (!isNull && !temp->isUndefined()) {
2701 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mRcwnCacheWonCount)) {
2702 0 : return false;
2703 : }
2704 : } else {
2705 0 : mRcwnCacheWonCount = 0U;
2706 : }
2707 0 : mIsAnyMemberPresent = true;
2708 :
2709 0 : if (!isNull) {
2710 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->rcwnNetWonCount_id, temp.ptr())) {
2711 0 : return false;
2712 : }
2713 : }
2714 0 : if (!isNull && !temp->isUndefined()) {
2715 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mRcwnNetWonCount)) {
2716 0 : return false;
2717 : }
2718 : } else {
2719 0 : mRcwnNetWonCount = 0U;
2720 : }
2721 0 : mIsAnyMemberPresent = true;
2722 :
2723 0 : if (!isNull) {
2724 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->totalNetworkRequests_id, temp.ptr())) {
2725 0 : return false;
2726 : }
2727 : }
2728 0 : if (!isNull && !temp->isUndefined()) {
2729 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mTotalNetworkRequests)) {
2730 0 : return false;
2731 : }
2732 : } else {
2733 0 : mTotalNetworkRequests = 0U;
2734 : }
2735 0 : mIsAnyMemberPresent = true;
2736 0 : return true;
2737 : }
2738 :
2739 : bool
2740 0 : RcwnStatus::Init(const nsAString& aJSON)
2741 : {
2742 0 : AutoJSAPI jsapi;
2743 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
2744 0 : if (!cleanGlobal) {
2745 0 : return false;
2746 : }
2747 0 : if (!jsapi.Init(cleanGlobal)) {
2748 0 : return false;
2749 : }
2750 0 : JSContext* cx = jsapi.cx();
2751 0 : JS::Rooted<JS::Value> json(cx);
2752 0 : bool ok = ParseJSON(cx, aJSON, &json);
2753 0 : NS_ENSURE_TRUE(ok, false);
2754 0 : return Init(cx, json);
2755 : }
2756 :
2757 : bool
2758 0 : RcwnStatus::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
2759 : {
2760 0 : RcwnStatusAtoms* atomsCache = GetAtomCache<RcwnStatusAtoms>(cx);
2761 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2762 0 : return false;
2763 : }
2764 :
2765 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
2766 0 : if (!obj) {
2767 0 : return false;
2768 : }
2769 0 : rval.set(JS::ObjectValue(*obj));
2770 :
2771 : do {
2772 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2773 0 : JS::Rooted<JS::Value> temp(cx);
2774 0 : uint32_t const & currentValue = mCacheNotSlowCount;
2775 0 : temp.setNumber(currentValue);
2776 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->cacheNotSlowCount_id, temp, JSPROP_ENUMERATE)) {
2777 0 : return false;
2778 : }
2779 0 : break;
2780 : } while(0);
2781 :
2782 : do {
2783 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2784 0 : JS::Rooted<JS::Value> temp(cx);
2785 0 : uint32_t const & currentValue = mCacheSlowCount;
2786 0 : temp.setNumber(currentValue);
2787 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->cacheSlowCount_id, temp, JSPROP_ENUMERATE)) {
2788 0 : return false;
2789 : }
2790 0 : break;
2791 : } while(0);
2792 :
2793 0 : if (mPerfStats.WasPassed()) {
2794 : do {
2795 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2796 0 : JS::Rooted<JS::Value> temp(cx);
2797 0 : Sequence<RcwnPerfStats> const & currentValue = mPerfStats.InternalValue();
2798 :
2799 0 : uint32_t length = currentValue.Length();
2800 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
2801 0 : if (!returnArray) {
2802 0 : return false;
2803 : }
2804 : // Scope for 'tmp'
2805 : {
2806 0 : JS::Rooted<JS::Value> tmp(cx);
2807 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
2808 : // Control block to let us common up the JS_DefineElement calls when there
2809 : // are different ways to succeed at wrapping the object.
2810 : do {
2811 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
2812 0 : return false;
2813 : }
2814 0 : break;
2815 : } while (0);
2816 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
2817 : JSPROP_ENUMERATE)) {
2818 0 : return false;
2819 : }
2820 : }
2821 : }
2822 0 : temp.setObject(*returnArray);
2823 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->perfStats_id, temp, JSPROP_ENUMERATE)) {
2824 0 : return false;
2825 : }
2826 0 : break;
2827 : } while(0);
2828 : }
2829 :
2830 : do {
2831 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2832 0 : JS::Rooted<JS::Value> temp(cx);
2833 0 : uint32_t const & currentValue = mRcwnCacheWonCount;
2834 0 : temp.setNumber(currentValue);
2835 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->rcwnCacheWonCount_id, temp, JSPROP_ENUMERATE)) {
2836 0 : return false;
2837 : }
2838 0 : break;
2839 : } while(0);
2840 :
2841 : do {
2842 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2843 0 : JS::Rooted<JS::Value> temp(cx);
2844 0 : uint32_t const & currentValue = mRcwnNetWonCount;
2845 0 : temp.setNumber(currentValue);
2846 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->rcwnNetWonCount_id, temp, JSPROP_ENUMERATE)) {
2847 0 : return false;
2848 : }
2849 0 : break;
2850 : } while(0);
2851 :
2852 : do {
2853 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2854 0 : JS::Rooted<JS::Value> temp(cx);
2855 0 : uint32_t const & currentValue = mTotalNetworkRequests;
2856 0 : temp.setNumber(currentValue);
2857 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->totalNetworkRequests_id, temp, JSPROP_ENUMERATE)) {
2858 0 : return false;
2859 : }
2860 0 : break;
2861 : } while(0);
2862 :
2863 0 : return true;
2864 : }
2865 :
2866 : bool
2867 0 : RcwnStatus::ToJSON(nsAString& aJSON) const
2868 : {
2869 0 : AutoJSAPI jsapi;
2870 0 : jsapi.Init();
2871 0 : JSContext *cx = jsapi.cx();
2872 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
2873 : // because we'll only be creating objects, in ways that have no
2874 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
2875 : // which likewise guarantees no side-effects for the sorts of
2876 : // things we will pass it.
2877 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
2878 0 : JS::Rooted<JS::Value> val(cx);
2879 0 : if (!ToObjectInternal(cx, &val)) {
2880 0 : return false;
2881 : }
2882 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
2883 0 : return StringifyToJSON(cx, obj, aJSON);
2884 : }
2885 :
2886 : void
2887 0 : RcwnStatus::TraceDictionary(JSTracer* trc)
2888 : {
2889 0 : }
2890 :
2891 : RcwnStatus&
2892 0 : RcwnStatus::operator=(const RcwnStatus& aOther)
2893 : {
2894 0 : mCacheNotSlowCount = aOther.mCacheNotSlowCount;
2895 0 : mCacheSlowCount = aOther.mCacheSlowCount;
2896 0 : mPerfStats.Reset();
2897 0 : if (aOther.mPerfStats.WasPassed()) {
2898 0 : mPerfStats.Construct(aOther.mPerfStats.Value());
2899 : }
2900 0 : mRcwnCacheWonCount = aOther.mRcwnCacheWonCount;
2901 0 : mRcwnNetWonCount = aOther.mRcwnNetWonCount;
2902 0 : mTotalNetworkRequests = aOther.mTotalNetworkRequests;
2903 0 : return *this;
2904 : }
2905 :
2906 : namespace binding_detail {
2907 : } // namespace binding_detail
2908 :
2909 :
2910 :
2911 0 : SocketsDict::SocketsDict()
2912 : {
2913 : // Safe to pass a null context if we pass a null value
2914 0 : Init(nullptr, JS::NullHandleValue);
2915 0 : }
2916 :
2917 :
2918 :
2919 : bool
2920 0 : SocketsDict::InitIds(JSContext* cx, SocketsDictAtoms* atomsCache)
2921 : {
2922 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
2923 :
2924 : // Initialize these in reverse order so that any failure leaves the first one
2925 : // uninitialized.
2926 0 : if (!atomsCache->sockets_id.init(cx, "sockets") ||
2927 0 : !atomsCache->sent_id.init(cx, "sent") ||
2928 0 : !atomsCache->received_id.init(cx, "received")) {
2929 0 : return false;
2930 : }
2931 0 : return true;
2932 : }
2933 :
2934 : bool
2935 0 : SocketsDict::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
2936 : {
2937 : // Passing a null JSContext is OK only if we're initing from null,
2938 : // Since in that case we will not have to do any property gets
2939 : // Also evaluate isNullOrUndefined in order to avoid false-positive
2940 : // checkers by static analysis tools
2941 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
2942 0 : SocketsDictAtoms* atomsCache = nullptr;
2943 0 : if (cx) {
2944 0 : atomsCache = GetAtomCache<SocketsDictAtoms>(cx);
2945 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2946 0 : return false;
2947 : }
2948 : }
2949 :
2950 0 : if (!IsConvertibleToDictionary(val)) {
2951 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
2952 : }
2953 :
2954 0 : bool isNull = val.isNullOrUndefined();
2955 : // We only need these if !isNull, in which case we have |cx|.
2956 0 : Maybe<JS::Rooted<JSObject *> > object;
2957 0 : Maybe<JS::Rooted<JS::Value> > temp;
2958 0 : if (!isNull) {
2959 0 : MOZ_ASSERT(cx);
2960 0 : object.emplace(cx, &val.toObject());
2961 0 : temp.emplace(cx);
2962 : }
2963 0 : if (!isNull) {
2964 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->received_id, temp.ptr())) {
2965 0 : return false;
2966 : }
2967 : }
2968 0 : if (!isNull && !temp->isUndefined()) {
2969 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &mReceived)) {
2970 0 : return false;
2971 0 : } else if (!mozilla::IsFinite(mReceived)) {
2972 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'received' member of SocketsDict");
2973 0 : return false;
2974 : }
2975 : } else {
2976 0 : mReceived = 0.0;
2977 : }
2978 0 : mIsAnyMemberPresent = true;
2979 :
2980 0 : if (!isNull) {
2981 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->sent_id, temp.ptr())) {
2982 0 : return false;
2983 : }
2984 : }
2985 0 : if (!isNull && !temp->isUndefined()) {
2986 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &mSent)) {
2987 0 : return false;
2988 0 : } else if (!mozilla::IsFinite(mSent)) {
2989 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'sent' member of SocketsDict");
2990 0 : return false;
2991 : }
2992 : } else {
2993 0 : mSent = 0.0;
2994 : }
2995 0 : mIsAnyMemberPresent = true;
2996 :
2997 0 : if (!isNull) {
2998 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->sockets_id, temp.ptr())) {
2999 0 : return false;
3000 : }
3001 : }
3002 0 : if (!isNull && !temp->isUndefined()) {
3003 0 : mSockets.Construct();
3004 0 : if (temp.ref().isObject()) {
3005 0 : JS::ForOfIterator iter(cx);
3006 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
3007 0 : return false;
3008 : }
3009 0 : if (!iter.valueIsIterable()) {
3010 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'sockets' member of SocketsDict");
3011 0 : return false;
3012 : }
3013 0 : Sequence<SocketElement> &arr = (mSockets.Value());
3014 0 : JS::Rooted<JS::Value> temp(cx);
3015 : while (true) {
3016 : bool done;
3017 0 : if (!iter.next(&temp, &done)) {
3018 0 : return false;
3019 : }
3020 0 : if (done) {
3021 0 : break;
3022 : }
3023 0 : SocketElement* slotPtr = arr.AppendElement(mozilla::fallible);
3024 0 : if (!slotPtr) {
3025 0 : JS_ReportOutOfMemory(cx);
3026 0 : return false;
3027 : }
3028 0 : SocketElement& slot = *slotPtr;
3029 0 : if (!slot.Init(cx, temp, "Element of 'sockets' member of SocketsDict", passedToJSImpl)) {
3030 0 : return false;
3031 : }
3032 0 : }
3033 : } else {
3034 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'sockets' member of SocketsDict");
3035 0 : return false;
3036 : }
3037 0 : mIsAnyMemberPresent = true;
3038 : }
3039 0 : return true;
3040 : }
3041 :
3042 : bool
3043 0 : SocketsDict::Init(const nsAString& aJSON)
3044 : {
3045 0 : AutoJSAPI jsapi;
3046 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
3047 0 : if (!cleanGlobal) {
3048 0 : return false;
3049 : }
3050 0 : if (!jsapi.Init(cleanGlobal)) {
3051 0 : return false;
3052 : }
3053 0 : JSContext* cx = jsapi.cx();
3054 0 : JS::Rooted<JS::Value> json(cx);
3055 0 : bool ok = ParseJSON(cx, aJSON, &json);
3056 0 : NS_ENSURE_TRUE(ok, false);
3057 0 : return Init(cx, json);
3058 : }
3059 :
3060 : bool
3061 0 : SocketsDict::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
3062 : {
3063 0 : SocketsDictAtoms* atomsCache = GetAtomCache<SocketsDictAtoms>(cx);
3064 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
3065 0 : return false;
3066 : }
3067 :
3068 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
3069 0 : if (!obj) {
3070 0 : return false;
3071 : }
3072 0 : rval.set(JS::ObjectValue(*obj));
3073 :
3074 : do {
3075 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3076 0 : JS::Rooted<JS::Value> temp(cx);
3077 0 : double const & currentValue = mReceived;
3078 0 : temp.set(JS_NumberValue(double(currentValue)));
3079 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->received_id, temp, JSPROP_ENUMERATE)) {
3080 0 : return false;
3081 : }
3082 0 : break;
3083 : } while(0);
3084 :
3085 : do {
3086 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3087 0 : JS::Rooted<JS::Value> temp(cx);
3088 0 : double const & currentValue = mSent;
3089 0 : temp.set(JS_NumberValue(double(currentValue)));
3090 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->sent_id, temp, JSPROP_ENUMERATE)) {
3091 0 : return false;
3092 : }
3093 0 : break;
3094 : } while(0);
3095 :
3096 0 : if (mSockets.WasPassed()) {
3097 : do {
3098 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3099 0 : JS::Rooted<JS::Value> temp(cx);
3100 0 : Sequence<SocketElement> const & currentValue = mSockets.InternalValue();
3101 :
3102 0 : uint32_t length = currentValue.Length();
3103 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
3104 0 : if (!returnArray) {
3105 0 : return false;
3106 : }
3107 : // Scope for 'tmp'
3108 : {
3109 0 : JS::Rooted<JS::Value> tmp(cx);
3110 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
3111 : // Control block to let us common up the JS_DefineElement calls when there
3112 : // are different ways to succeed at wrapping the object.
3113 : do {
3114 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
3115 0 : return false;
3116 : }
3117 0 : break;
3118 : } while (0);
3119 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
3120 : JSPROP_ENUMERATE)) {
3121 0 : return false;
3122 : }
3123 : }
3124 : }
3125 0 : temp.setObject(*returnArray);
3126 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->sockets_id, temp, JSPROP_ENUMERATE)) {
3127 0 : return false;
3128 : }
3129 0 : break;
3130 : } while(0);
3131 : }
3132 :
3133 0 : return true;
3134 : }
3135 :
3136 : bool
3137 0 : SocketsDict::ToJSON(nsAString& aJSON) const
3138 : {
3139 0 : AutoJSAPI jsapi;
3140 0 : jsapi.Init();
3141 0 : JSContext *cx = jsapi.cx();
3142 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
3143 : // because we'll only be creating objects, in ways that have no
3144 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
3145 : // which likewise guarantees no side-effects for the sorts of
3146 : // things we will pass it.
3147 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
3148 0 : JS::Rooted<JS::Value> val(cx);
3149 0 : if (!ToObjectInternal(cx, &val)) {
3150 0 : return false;
3151 : }
3152 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
3153 0 : return StringifyToJSON(cx, obj, aJSON);
3154 : }
3155 :
3156 : void
3157 0 : SocketsDict::TraceDictionary(JSTracer* trc)
3158 : {
3159 0 : }
3160 :
3161 : SocketsDict&
3162 0 : SocketsDict::operator=(const SocketsDict& aOther)
3163 : {
3164 0 : mReceived = aOther.mReceived;
3165 0 : mSent = aOther.mSent;
3166 0 : mSockets.Reset();
3167 0 : if (aOther.mSockets.WasPassed()) {
3168 0 : mSockets.Construct(aOther.mSockets.Value());
3169 : }
3170 0 : return *this;
3171 : }
3172 :
3173 : namespace binding_detail {
3174 : } // namespace binding_detail
3175 :
3176 :
3177 :
3178 0 : WebSocketDict::WebSocketDict()
3179 : {
3180 : // Safe to pass a null context if we pass a null value
3181 0 : Init(nullptr, JS::NullHandleValue);
3182 0 : }
3183 :
3184 :
3185 :
3186 : bool
3187 0 : WebSocketDict::InitIds(JSContext* cx, WebSocketDictAtoms* atomsCache)
3188 : {
3189 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
3190 :
3191 : // Initialize these in reverse order so that any failure leaves the first one
3192 : // uninitialized.
3193 0 : if (!atomsCache->websockets_id.init(cx, "websockets")) {
3194 0 : return false;
3195 : }
3196 0 : return true;
3197 : }
3198 :
3199 : bool
3200 0 : WebSocketDict::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
3201 : {
3202 : // Passing a null JSContext is OK only if we're initing from null,
3203 : // Since in that case we will not have to do any property gets
3204 : // Also evaluate isNullOrUndefined in order to avoid false-positive
3205 : // checkers by static analysis tools
3206 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
3207 0 : WebSocketDictAtoms* atomsCache = nullptr;
3208 0 : if (cx) {
3209 0 : atomsCache = GetAtomCache<WebSocketDictAtoms>(cx);
3210 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
3211 0 : return false;
3212 : }
3213 : }
3214 :
3215 0 : if (!IsConvertibleToDictionary(val)) {
3216 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
3217 : }
3218 :
3219 0 : bool isNull = val.isNullOrUndefined();
3220 : // We only need these if !isNull, in which case we have |cx|.
3221 0 : Maybe<JS::Rooted<JSObject *> > object;
3222 0 : Maybe<JS::Rooted<JS::Value> > temp;
3223 0 : if (!isNull) {
3224 0 : MOZ_ASSERT(cx);
3225 0 : object.emplace(cx, &val.toObject());
3226 0 : temp.emplace(cx);
3227 : }
3228 0 : if (!isNull) {
3229 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->websockets_id, temp.ptr())) {
3230 0 : return false;
3231 : }
3232 : }
3233 0 : if (!isNull && !temp->isUndefined()) {
3234 0 : mWebsockets.Construct();
3235 0 : if (temp.ref().isObject()) {
3236 0 : JS::ForOfIterator iter(cx);
3237 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
3238 0 : return false;
3239 : }
3240 0 : if (!iter.valueIsIterable()) {
3241 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'websockets' member of WebSocketDict");
3242 0 : return false;
3243 : }
3244 0 : Sequence<WebSocketElement> &arr = (mWebsockets.Value());
3245 0 : JS::Rooted<JS::Value> temp(cx);
3246 : while (true) {
3247 : bool done;
3248 0 : if (!iter.next(&temp, &done)) {
3249 0 : return false;
3250 : }
3251 0 : if (done) {
3252 0 : break;
3253 : }
3254 0 : WebSocketElement* slotPtr = arr.AppendElement(mozilla::fallible);
3255 0 : if (!slotPtr) {
3256 0 : JS_ReportOutOfMemory(cx);
3257 0 : return false;
3258 : }
3259 0 : WebSocketElement& slot = *slotPtr;
3260 0 : if (!slot.Init(cx, temp, "Element of 'websockets' member of WebSocketDict", passedToJSImpl)) {
3261 0 : return false;
3262 : }
3263 0 : }
3264 : } else {
3265 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'websockets' member of WebSocketDict");
3266 0 : return false;
3267 : }
3268 0 : mIsAnyMemberPresent = true;
3269 : }
3270 0 : return true;
3271 : }
3272 :
3273 : bool
3274 0 : WebSocketDict::Init(const nsAString& aJSON)
3275 : {
3276 0 : AutoJSAPI jsapi;
3277 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
3278 0 : if (!cleanGlobal) {
3279 0 : return false;
3280 : }
3281 0 : if (!jsapi.Init(cleanGlobal)) {
3282 0 : return false;
3283 : }
3284 0 : JSContext* cx = jsapi.cx();
3285 0 : JS::Rooted<JS::Value> json(cx);
3286 0 : bool ok = ParseJSON(cx, aJSON, &json);
3287 0 : NS_ENSURE_TRUE(ok, false);
3288 0 : return Init(cx, json);
3289 : }
3290 :
3291 : bool
3292 0 : WebSocketDict::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
3293 : {
3294 0 : WebSocketDictAtoms* atomsCache = GetAtomCache<WebSocketDictAtoms>(cx);
3295 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
3296 0 : return false;
3297 : }
3298 :
3299 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
3300 0 : if (!obj) {
3301 0 : return false;
3302 : }
3303 0 : rval.set(JS::ObjectValue(*obj));
3304 :
3305 0 : if (mWebsockets.WasPassed()) {
3306 : do {
3307 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3308 0 : JS::Rooted<JS::Value> temp(cx);
3309 0 : Sequence<WebSocketElement> const & currentValue = mWebsockets.InternalValue();
3310 :
3311 0 : uint32_t length = currentValue.Length();
3312 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
3313 0 : if (!returnArray) {
3314 0 : return false;
3315 : }
3316 : // Scope for 'tmp'
3317 : {
3318 0 : JS::Rooted<JS::Value> tmp(cx);
3319 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
3320 : // Control block to let us common up the JS_DefineElement calls when there
3321 : // are different ways to succeed at wrapping the object.
3322 : do {
3323 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
3324 0 : return false;
3325 : }
3326 0 : break;
3327 : } while (0);
3328 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
3329 : JSPROP_ENUMERATE)) {
3330 0 : return false;
3331 : }
3332 : }
3333 : }
3334 0 : temp.setObject(*returnArray);
3335 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->websockets_id, temp, JSPROP_ENUMERATE)) {
3336 0 : return false;
3337 : }
3338 0 : break;
3339 : } while(0);
3340 : }
3341 :
3342 0 : return true;
3343 : }
3344 :
3345 : bool
3346 0 : WebSocketDict::ToJSON(nsAString& aJSON) const
3347 : {
3348 0 : AutoJSAPI jsapi;
3349 0 : jsapi.Init();
3350 0 : JSContext *cx = jsapi.cx();
3351 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
3352 : // because we'll only be creating objects, in ways that have no
3353 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
3354 : // which likewise guarantees no side-effects for the sorts of
3355 : // things we will pass it.
3356 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
3357 0 : JS::Rooted<JS::Value> val(cx);
3358 0 : if (!ToObjectInternal(cx, &val)) {
3359 0 : return false;
3360 : }
3361 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
3362 0 : return StringifyToJSON(cx, obj, aJSON);
3363 : }
3364 :
3365 : void
3366 0 : WebSocketDict::TraceDictionary(JSTracer* trc)
3367 : {
3368 0 : }
3369 :
3370 : WebSocketDict&
3371 0 : WebSocketDict::operator=(const WebSocketDict& aOther)
3372 : {
3373 0 : mWebsockets.Reset();
3374 0 : if (aOther.mWebsockets.WasPassed()) {
3375 0 : mWebsockets.Construct(aOther.mWebsockets.Value());
3376 : }
3377 0 : return *this;
3378 : }
3379 :
3380 : namespace binding_detail {
3381 : } // namespace binding_detail
3382 :
3383 :
3384 :
3385 0 : HttpConnDict::HttpConnDict()
3386 : {
3387 : // Safe to pass a null context if we pass a null value
3388 0 : Init(nullptr, JS::NullHandleValue);
3389 0 : }
3390 :
3391 :
3392 :
3393 : bool
3394 0 : HttpConnDict::InitIds(JSContext* cx, HttpConnDictAtoms* atomsCache)
3395 : {
3396 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
3397 :
3398 : // Initialize these in reverse order so that any failure leaves the first one
3399 : // uninitialized.
3400 0 : if (!atomsCache->connections_id.init(cx, "connections")) {
3401 0 : return false;
3402 : }
3403 0 : return true;
3404 : }
3405 :
3406 : bool
3407 0 : HttpConnDict::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
3408 : {
3409 : // Passing a null JSContext is OK only if we're initing from null,
3410 : // Since in that case we will not have to do any property gets
3411 : // Also evaluate isNullOrUndefined in order to avoid false-positive
3412 : // checkers by static analysis tools
3413 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
3414 0 : HttpConnDictAtoms* atomsCache = nullptr;
3415 0 : if (cx) {
3416 0 : atomsCache = GetAtomCache<HttpConnDictAtoms>(cx);
3417 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
3418 0 : return false;
3419 : }
3420 : }
3421 :
3422 0 : if (!IsConvertibleToDictionary(val)) {
3423 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
3424 : }
3425 :
3426 0 : bool isNull = val.isNullOrUndefined();
3427 : // We only need these if !isNull, in which case we have |cx|.
3428 0 : Maybe<JS::Rooted<JSObject *> > object;
3429 0 : Maybe<JS::Rooted<JS::Value> > temp;
3430 0 : if (!isNull) {
3431 0 : MOZ_ASSERT(cx);
3432 0 : object.emplace(cx, &val.toObject());
3433 0 : temp.emplace(cx);
3434 : }
3435 0 : if (!isNull) {
3436 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->connections_id, temp.ptr())) {
3437 0 : return false;
3438 : }
3439 : }
3440 0 : if (!isNull && !temp->isUndefined()) {
3441 0 : mConnections.Construct();
3442 0 : if (temp.ref().isObject()) {
3443 0 : JS::ForOfIterator iter(cx);
3444 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
3445 0 : return false;
3446 : }
3447 0 : if (!iter.valueIsIterable()) {
3448 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'connections' member of HttpConnDict");
3449 0 : return false;
3450 : }
3451 0 : Sequence<HttpConnectionElement> &arr = (mConnections.Value());
3452 0 : JS::Rooted<JS::Value> temp(cx);
3453 : while (true) {
3454 : bool done;
3455 0 : if (!iter.next(&temp, &done)) {
3456 0 : return false;
3457 : }
3458 0 : if (done) {
3459 0 : break;
3460 : }
3461 0 : HttpConnectionElement* slotPtr = arr.AppendElement(mozilla::fallible);
3462 0 : if (!slotPtr) {
3463 0 : JS_ReportOutOfMemory(cx);
3464 0 : return false;
3465 : }
3466 0 : HttpConnectionElement& slot = *slotPtr;
3467 0 : if (!slot.Init(cx, temp, "Element of 'connections' member of HttpConnDict", passedToJSImpl)) {
3468 0 : return false;
3469 : }
3470 0 : }
3471 : } else {
3472 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'connections' member of HttpConnDict");
3473 0 : return false;
3474 : }
3475 0 : mIsAnyMemberPresent = true;
3476 : }
3477 0 : return true;
3478 : }
3479 :
3480 : bool
3481 0 : HttpConnDict::Init(const nsAString& aJSON)
3482 : {
3483 0 : AutoJSAPI jsapi;
3484 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
3485 0 : if (!cleanGlobal) {
3486 0 : return false;
3487 : }
3488 0 : if (!jsapi.Init(cleanGlobal)) {
3489 0 : return false;
3490 : }
3491 0 : JSContext* cx = jsapi.cx();
3492 0 : JS::Rooted<JS::Value> json(cx);
3493 0 : bool ok = ParseJSON(cx, aJSON, &json);
3494 0 : NS_ENSURE_TRUE(ok, false);
3495 0 : return Init(cx, json);
3496 : }
3497 :
3498 : bool
3499 0 : HttpConnDict::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
3500 : {
3501 0 : HttpConnDictAtoms* atomsCache = GetAtomCache<HttpConnDictAtoms>(cx);
3502 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
3503 0 : return false;
3504 : }
3505 :
3506 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
3507 0 : if (!obj) {
3508 0 : return false;
3509 : }
3510 0 : rval.set(JS::ObjectValue(*obj));
3511 :
3512 0 : if (mConnections.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 : Sequence<HttpConnectionElement> const & currentValue = mConnections.InternalValue();
3517 :
3518 0 : uint32_t length = currentValue.Length();
3519 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
3520 0 : if (!returnArray) {
3521 0 : return false;
3522 : }
3523 : // Scope for 'tmp'
3524 : {
3525 0 : JS::Rooted<JS::Value> tmp(cx);
3526 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
3527 : // Control block to let us common up the JS_DefineElement calls when there
3528 : // are different ways to succeed at wrapping the object.
3529 : do {
3530 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
3531 0 : return false;
3532 : }
3533 0 : break;
3534 : } while (0);
3535 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
3536 : JSPROP_ENUMERATE)) {
3537 0 : return false;
3538 : }
3539 : }
3540 : }
3541 0 : temp.setObject(*returnArray);
3542 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->connections_id, temp, JSPROP_ENUMERATE)) {
3543 0 : return false;
3544 : }
3545 0 : break;
3546 : } while(0);
3547 : }
3548 :
3549 0 : return true;
3550 : }
3551 :
3552 : bool
3553 0 : HttpConnDict::ToJSON(nsAString& aJSON) const
3554 : {
3555 0 : AutoJSAPI jsapi;
3556 0 : jsapi.Init();
3557 0 : JSContext *cx = jsapi.cx();
3558 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
3559 : // because we'll only be creating objects, in ways that have no
3560 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
3561 : // which likewise guarantees no side-effects for the sorts of
3562 : // things we will pass it.
3563 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
3564 0 : JS::Rooted<JS::Value> val(cx);
3565 0 : if (!ToObjectInternal(cx, &val)) {
3566 0 : return false;
3567 : }
3568 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
3569 0 : return StringifyToJSON(cx, obj, aJSON);
3570 : }
3571 :
3572 : void
3573 0 : HttpConnDict::TraceDictionary(JSTracer* trc)
3574 : {
3575 0 : }
3576 :
3577 : HttpConnDict&
3578 0 : HttpConnDict::operator=(const HttpConnDict& aOther)
3579 : {
3580 0 : mConnections.Reset();
3581 0 : if (aOther.mConnections.WasPassed()) {
3582 0 : mConnections.Construct(aOther.mConnections.Value());
3583 : }
3584 0 : return *this;
3585 : }
3586 :
3587 : namespace binding_detail {
3588 : } // namespace binding_detail
3589 :
3590 :
3591 : } // namespace dom
3592 : } // namespace mozilla
|