Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/PrioEncoderBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM PrioEncoder.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "AtomList.h"
4
#include "PrioEncoderBinding.h"
5
#include "WrapperFactory.h"
6
#include "jsfriendapi.h"
7
#include "mozilla/OwningNonNull.h"
8
#include "mozilla/dom/BindingUtils.h"
9
#include "mozilla/dom/DOMJSClass.h"
10
#include "mozilla/dom/NonRefcountedDOMObject.h"
11
#include "mozilla/dom/PrimitiveConversions.h"
12
#include "mozilla/dom/PrioEncoder.h"
13
#include "mozilla/dom/ScriptSettings.h"
14
#include "mozilla/dom/SimpleGlobalObject.h"
15
#include "mozilla/dom/XrayExpandoClass.h"
16
#include "nsContentUtils.h"
17
18
namespace mozilla {
19
namespace dom {
20
21
namespace binding_detail {}; // Just to make sure it's known as a namespace
22
using namespace mozilla::dom::binding_detail;
23
24
25
26
PrioEncodedData::PrioEncodedData()
27
0
{
28
0
  // Safe to pass a null context if we pass a null value
29
0
  Init(nullptr, JS::NullHandleValue);
30
0
}
31
32
33
bool
34
PrioEncodedData::InitIds(JSContext* cx, PrioEncodedDataAtoms* atomsCache)
35
0
{
36
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
37
0
38
0
  // Initialize these in reverse order so that any failure leaves the first one
39
0
  // uninitialized.
40
0
  if (!atomsCache->b_id.init(cx, "b") ||
41
0
      !atomsCache->a_id.init(cx, "a")) {
42
0
    return false;
43
0
  }
44
0
  return true;
45
0
}
46
47
bool
48
PrioEncodedData::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
49
0
{
50
0
  // Passing a null JSContext is OK only if we're initing from null,
51
0
  // Since in that case we will not have to do any property gets
52
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
53
0
  // checkers by static analysis tools
54
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
55
0
  PrioEncodedDataAtoms* atomsCache = nullptr;
56
0
  if (cx) {
57
0
    atomsCache = GetAtomCache<PrioEncodedDataAtoms>(cx);
58
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
59
0
      return false;
60
0
    }
61
0
  }
62
0
63
0
  if (!IsConvertibleToDictionary(val)) {
64
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
65
0
  }
66
0
67
0
  bool isNull = val.isNullOrUndefined();
68
0
  // We only need these if !isNull, in which case we have |cx|.
69
0
  Maybe<JS::Rooted<JSObject *> > object;
70
0
  Maybe<JS::Rooted<JS::Value> > temp;
71
0
  if (!isNull) {
72
0
    MOZ_ASSERT(cx);
73
0
    object.emplace(cx, &val.toObject());
74
0
    temp.emplace(cx);
75
0
  }
76
0
  if (!isNull) {
77
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->a_id, temp.ptr())) {
78
0
      return false;
79
0
    }
80
0
  }
81
0
  if (!isNull && !temp->isUndefined()) {
82
0
    mA.Construct();
83
0
    if (temp.ref().isObject()) {
84
0
      if (!(mA.Value()).Init(&temp.ref().toObject())) {
85
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "'a' member of PrioEncodedData", "Uint8Array");
86
0
        return false;
87
0
      }
88
0
    } else {
89
0
      ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'a' member of PrioEncodedData");
90
0
      return false;
91
0
    }
92
0
    mIsAnyMemberPresent = true;
93
0
  }
94
0
95
0
  if (!isNull) {
96
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->b_id, temp.ptr())) {
97
0
      return false;
98
0
    }
99
0
  }
100
0
  if (!isNull && !temp->isUndefined()) {
101
0
    mB.Construct();
102
0
    if (temp.ref().isObject()) {
103
0
      if (!(mB.Value()).Init(&temp.ref().toObject())) {
104
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "'b' member of PrioEncodedData", "Uint8Array");
105
0
        return false;
106
0
      }
107
0
    } else {
108
0
      ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'b' member of PrioEncodedData");
109
0
      return false;
110
0
    }
111
0
    mIsAnyMemberPresent = true;
112
0
  }
113
0
  return true;
114
0
}
115
116
bool
117
PrioEncodedData::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
118
0
{
119
0
  PrioEncodedDataAtoms* atomsCache = GetAtomCache<PrioEncodedDataAtoms>(cx);
120
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
121
0
    return false;
122
0
  }
123
0
124
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
125
0
  if (!obj) {
126
0
    return false;
127
0
  }
128
0
  rval.set(JS::ObjectValue(*obj));
129
0
130
0
  if (mA.WasPassed()) {
131
0
    do {
132
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
133
0
      JS::Rooted<JS::Value> temp(cx);
134
0
      Uint8Array const & currentValue = mA.InternalValue();
135
0
      temp.setObject(*currentValue.Obj());
136
0
      if (!MaybeWrapNonDOMObjectValue(cx, &temp)) {
137
0
        return false;
138
0
      }
139
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->a_id, temp, JSPROP_ENUMERATE)) {
140
0
        return false;
141
0
      }
142
0
      break;
143
0
    } while(false);
144
0
  }
145
0
146
0
  if (mB.WasPassed()) {
147
0
    do {
148
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
149
0
      JS::Rooted<JS::Value> temp(cx);
150
0
      Uint8Array const & currentValue = mB.InternalValue();
151
0
      temp.setObject(*currentValue.Obj());
152
0
      if (!MaybeWrapNonDOMObjectValue(cx, &temp)) {
153
0
        return false;
154
0
      }
155
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->b_id, temp, JSPROP_ENUMERATE)) {
156
0
        return false;
157
0
      }
158
0
      break;
159
0
    } while(false);
160
0
  }
161
0
162
0
  return true;
163
0
}
164
165
void
166
PrioEncodedData::TraceDictionary(JSTracer* trc)
167
0
{
168
0
  if (mA.WasPassed()) {
169
0
    mA.Value().TraceSelf(trc);
170
0
  }
171
0
172
0
  if (mB.WasPassed()) {
173
0
    mB.Value().TraceSelf(trc);
174
0
  }
175
0
}
176
177
namespace binding_detail {
178
} // namespace binding_detail
179
180
181
182
PrioParams::PrioParams()
183
0
{
184
0
  // Safe to pass a null context if we pass a null value
185
0
  Init(nullptr, JS::NullHandleValue);
186
0
}
187
188
189
190
bool
191
PrioParams::InitIds(JSContext* cx, PrioParamsAtoms* atomsCache)
192
0
{
193
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
194
0
195
0
  // Initialize these in reverse order so that any failure leaves the first one
196
0
  // uninitialized.
197
0
  if (!atomsCache->pdfViewerUsed_id.init(cx, "pdfViewerUsed") ||
198
0
      !atomsCache->newTabPageEnabled_id.init(cx, "newTabPageEnabled") ||
199
0
      !atomsCache->browserIsUserDefault_id.init(cx, "browserIsUserDefault")) {
200
0
    return false;
201
0
  }
202
0
  return true;
203
0
}
204
205
bool
206
PrioParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
207
0
{
208
0
  // Passing a null JSContext is OK only if we're initing from null,
209
0
  // Since in that case we will not have to do any property gets
210
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
211
0
  // checkers by static analysis tools
212
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
213
0
  PrioParamsAtoms* atomsCache = nullptr;
214
0
  if (cx) {
215
0
    atomsCache = GetAtomCache<PrioParamsAtoms>(cx);
216
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
217
0
      return false;
218
0
    }
219
0
  }
220
0
221
0
  if (!IsConvertibleToDictionary(val)) {
222
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
223
0
  }
224
0
225
0
  bool isNull = val.isNullOrUndefined();
226
0
  // We only need these if !isNull, in which case we have |cx|.
227
0
  Maybe<JS::Rooted<JSObject *> > object;
228
0
  Maybe<JS::Rooted<JS::Value> > temp;
229
0
  if (!isNull) {
230
0
    MOZ_ASSERT(cx);
231
0
    object.emplace(cx, &val.toObject());
232
0
    temp.emplace(cx);
233
0
  }
234
0
  if (!isNull) {
235
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->browserIsUserDefault_id, temp.ptr())) {
236
0
      return false;
237
0
    }
238
0
  }
239
0
  if (!isNull && !temp->isUndefined()) {
240
0
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mBrowserIsUserDefault)) {
241
0
      return false;
242
0
    }
243
0
    mIsAnyMemberPresent = true;
244
0
  } else if (cx) {
245
0
    // Don't error out if we have no cx.  In that
246
0
    // situation the caller is default-constructing us and we'll
247
0
    // just assume they know what they're doing.
248
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
249
0
                             "'browserIsUserDefault' member of PrioParams");
250
0
  }
251
0
252
0
  if (!isNull) {
253
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->newTabPageEnabled_id, temp.ptr())) {
254
0
      return false;
255
0
    }
256
0
  }
257
0
  if (!isNull && !temp->isUndefined()) {
258
0
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mNewTabPageEnabled)) {
259
0
      return false;
260
0
    }
261
0
    mIsAnyMemberPresent = true;
262
0
  } else if (cx) {
263
0
    // Don't error out if we have no cx.  In that
264
0
    // situation the caller is default-constructing us and we'll
265
0
    // just assume they know what they're doing.
266
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
267
0
                             "'newTabPageEnabled' member of PrioParams");
268
0
  }
269
0
270
0
  if (!isNull) {
271
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->pdfViewerUsed_id, temp.ptr())) {
272
0
      return false;
273
0
    }
274
0
  }
275
0
  if (!isNull && !temp->isUndefined()) {
276
0
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mPdfViewerUsed)) {
277
0
      return false;
278
0
    }
279
0
    mIsAnyMemberPresent = true;
280
0
  } else if (cx) {
281
0
    // Don't error out if we have no cx.  In that
282
0
    // situation the caller is default-constructing us and we'll
283
0
    // just assume they know what they're doing.
284
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
285
0
                             "'pdfViewerUsed' member of PrioParams");
286
0
  }
287
0
  return true;
288
0
}
289
290
bool
291
PrioParams::Init(const nsAString& aJSON)
292
0
{
293
0
  AutoJSAPI jsapi;
294
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
295
0
  if (!cleanGlobal) {
296
0
    return false;
297
0
  }
298
0
  if (!jsapi.Init(cleanGlobal)) {
299
0
    return false;
300
0
  }
301
0
  JSContext* cx = jsapi.cx();
302
0
  JS::Rooted<JS::Value> json(cx);
303
0
  bool ok = ParseJSON(cx, aJSON, &json);
304
0
  NS_ENSURE_TRUE(ok, false);
305
0
  return Init(cx, json);
306
0
}
307
308
bool
309
PrioParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
310
0
{
311
0
  PrioParamsAtoms* atomsCache = GetAtomCache<PrioParamsAtoms>(cx);
312
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
313
0
    return false;
314
0
  }
315
0
316
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
317
0
  if (!obj) {
318
0
    return false;
319
0
  }
320
0
  rval.set(JS::ObjectValue(*obj));
321
0
322
0
  do {
323
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
324
0
    JS::Rooted<JS::Value> temp(cx);
325
0
    bool const & currentValue = mBrowserIsUserDefault;
326
0
    temp.setBoolean(currentValue);
327
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->browserIsUserDefault_id, temp, JSPROP_ENUMERATE)) {
328
0
      return false;
329
0
    }
330
0
    break;
331
0
  } while(false);
332
0
333
0
  do {
334
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
335
0
    JS::Rooted<JS::Value> temp(cx);
336
0
    bool const & currentValue = mNewTabPageEnabled;
337
0
    temp.setBoolean(currentValue);
338
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->newTabPageEnabled_id, temp, JSPROP_ENUMERATE)) {
339
0
      return false;
340
0
    }
341
0
    break;
342
0
  } while(false);
343
0
344
0
  do {
345
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
346
0
    JS::Rooted<JS::Value> temp(cx);
347
0
    bool const & currentValue = mPdfViewerUsed;
348
0
    temp.setBoolean(currentValue);
349
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->pdfViewerUsed_id, temp, JSPROP_ENUMERATE)) {
350
0
      return false;
351
0
    }
352
0
    break;
353
0
  } while(false);
354
0
355
0
  return true;
356
0
}
357
358
bool
359
PrioParams::ToJSON(nsAString& aJSON) const
360
0
{
361
0
  AutoJSAPI jsapi;
362
0
  jsapi.Init();
363
0
  JSContext *cx = jsapi.cx();
364
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
365
0
  // because we'll only be creating objects, in ways that have no
366
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
367
0
  // which likewise guarantees no side-effects for the sorts of
368
0
  // things we will pass it.
369
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
370
0
  JS::Rooted<JS::Value> val(cx);
371
0
  if (!ToObjectInternal(cx, &val)) {
372
0
    return false;
373
0
  }
374
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
375
0
  return StringifyToJSON(cx, obj, aJSON);
376
0
}
377
378
void
379
PrioParams::TraceDictionary(JSTracer* trc)
380
0
{
381
0
}
382
383
PrioParams&
384
PrioParams::operator=(const PrioParams& aOther)
385
0
{
386
0
  DictionaryBase::operator=(aOther);
387
0
  mBrowserIsUserDefault = aOther.mBrowserIsUserDefault;
388
0
  mNewTabPageEnabled = aOther.mNewTabPageEnabled;
389
0
  mPdfViewerUsed = aOther.mPdfViewerUsed;
390
0
  return *this;
391
0
}
392
393
namespace binding_detail {
394
} // namespace binding_detail
395
396
397
namespace PrioEncoder_Binding {
398
399
static bool
400
encode(JSContext* cx, unsigned argc, JS::Value* vp)
401
0
{
402
0
  AUTO_PROFILER_LABEL_FAST("PrioEncoder.encode", DOM, cx);
403
0
404
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
405
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
406
0
407
0
  if (MOZ_UNLIKELY(args.length() < 2)) {
408
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "PrioEncoder.encode");
409
0
  }
410
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
411
0
  if (global.Failed()) {
412
0
    return false;
413
0
  }
414
0
415
0
  nsCString arg0;
416
0
  if (!ConvertJSValueToByteString(cx, args[0], false, arg0)) {
417
0
    return false;
418
0
  }
419
0
  binding_detail::FastPrioParams arg1;
420
0
  if (!arg1.Init(cx, args[1],  "Argument 2 of PrioEncoder.encode", false)) {
421
0
    return false;
422
0
  }
423
0
  FastErrorResult rv;
424
0
  RootedDictionary<PrioEncodedData> result(cx);
425
0
  mozilla::dom::PrioEncoder::Encode(global, Constify(arg0), Constify(arg1), result, rv);
426
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
427
0
    return false;
428
0
  }
429
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
430
0
  if (!result.ToObjectInternal(cx, args.rval())) {
431
0
    return false;
432
0
  }
433
0
  return true;
434
0
}
435
436
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
437
#if defined(__clang__)
438
#pragma clang diagnostic push
439
#pragma clang diagnostic ignored "-Wmissing-braces"
440
#endif
441
static const JSFunctionSpec sStaticMethods_specs[] = {
442
  JS_FNSPEC("encode", encode, nullptr, 2, JSPROP_ENUMERATE, nullptr),
443
  JS_FS_END
444
};
445
#if defined(__clang__)
446
#pragma clang diagnostic pop
447
#endif
448
449
450
static const Prefable<const JSFunctionSpec> sStaticMethods[] = {
451
  { nullptr, &sStaticMethods_specs[0] },
452
  { nullptr, nullptr }
453
};
454
455
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
456
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
457
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
458
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
459
460
461
static uint16_t sNativeProperties_sortedPropertyIndices[1];
462
static PropertyInfo sNativeProperties_propertyInfos[1];
463
464
static const NativePropertiesN<1> sNativeProperties = {
465
  true,  0 /* sStaticMethods */,
466
  false, 0,
467
  false, 0,
468
  false, 0,
469
  false, 0,
470
  false, 0,
471
  false, 0,
472
  -1,
473
  1,
474
  sNativeProperties_sortedPropertyIndices,
475
  {
476
    { sStaticMethods, &sNativeProperties_propertyInfos[0] }
477
  }
478
};
479
static_assert(1 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
480
    "We have a property info count that is oversized");
481
482
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
483
  {
484
    "Object",
485
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
486
    JS_NULL_CLASS_OPS,
487
    JS_NULL_CLASS_SPEC,
488
    JS_NULL_CLASS_EXT,
489
    JS_NULL_OBJECT_OPS
490
  },
491
  eInterface,
492
  false,
493
  prototypes::id::_ID_Count,
494
  0,
495
  sNativePropertyHooks,
496
  "[object Object]",
497
  JS::GetRealmObjectPrototype
498
};
499
500
bool
501
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
502
0
{
503
0
  return nsContentUtils::ThreadsafeIsSystemCaller(aCx);
504
0
}
505
506
const NativePropertyHooks sNativePropertyHooks[] = { {
507
  nullptr,
508
  nullptr,
509
  nullptr,
510
  { sNativeProperties.Upcast(), nullptr },
511
  prototypes::id::_ID_Count,
512
  constructors::id::PrioEncoder,
513
  nullptr,
514
  &DefaultXrayExpandoObjectClass
515
} };
516
517
void
518
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
519
0
{
520
0
  JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmObjectPrototype(aCx));
521
0
  if (!constructorProto) {
522
0
    return;
523
0
  }
524
0
525
0
  static bool sIdsInited = false;
526
0
  if (!sIdsInited && NS_IsMainThread()) {
527
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
528
0
      return;
529
0
    }
530
0
    sIdsInited = true;
531
0
  }
532
0
533
0
  JS::Heap<JSObject*>* protoCache = nullptr;
534
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::PrioEncoder);
535
0
  dom::CreateInterfaceObjects(aCx, aGlobal, nullptr,
536
0
                              nullptr, protoCache,
537
0
                              nullptr,
538
0
                              constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
539
0
                              interfaceCache,
540
0
                              sNativeProperties.Upcast(),
541
0
                              nullptr,
542
0
                              "PrioEncoder", aDefineOnGlobal,
543
0
                              nullptr,
544
0
                              false);
545
0
}
546
547
JSObject*
548
GetConstructorObject(JSContext* aCx)
549
0
{
550
0
  return GetConstructorObjectHandle(aCx);
551
0
}
552
553
} // namespace PrioEncoder_Binding
554
555
556
557
} // namespace dom
558
} // namespace mozilla