Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/IterableIteratorBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM IterableIterator.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "AtomList.h"
4
#include "IterableIteratorBinding.h"
5
#include "mozilla/OwningNonNull.h"
6
#include "mozilla/dom/BindingUtils.h"
7
#include "mozilla/dom/NonRefcountedDOMObject.h"
8
#include "mozilla/dom/PrimitiveConversions.h"
9
#include "mozilla/dom/ScriptSettings.h"
10
11
namespace mozilla {
12
namespace dom {
13
14
namespace binding_detail {}; // Just to make sure it's known as a namespace
15
using namespace mozilla::dom::binding_detail;
16
17
18
19
IterableKeyAndValueResult::IterableKeyAndValueResult()
20
0
{
21
0
  // Safe to pass a null context if we pass a null value
22
0
  Init(nullptr, JS::NullHandleValue);
23
0
}
24
25
26
bool
27
IterableKeyAndValueResult::InitIds(JSContext* cx, IterableKeyAndValueResultAtoms* atomsCache)
28
0
{
29
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
30
0
31
0
  // Initialize these in reverse order so that any failure leaves the first one
32
0
  // uninitialized.
33
0
  if (!atomsCache->value_id.init(cx, "value") ||
34
0
      !atomsCache->done_id.init(cx, "done")) {
35
0
    return false;
36
0
  }
37
0
  return true;
38
0
}
39
40
bool
41
IterableKeyAndValueResult::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
42
0
{
43
0
  // Passing a null JSContext is OK only if we're initing from null,
44
0
  // Since in that case we will not have to do any property gets
45
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
46
0
  // checkers by static analysis tools
47
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
48
0
  IterableKeyAndValueResultAtoms* atomsCache = nullptr;
49
0
  if (cx) {
50
0
    atomsCache = GetAtomCache<IterableKeyAndValueResultAtoms>(cx);
51
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
52
0
      return false;
53
0
    }
54
0
  }
55
0
56
0
  if (!IsConvertibleToDictionary(val)) {
57
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
58
0
  }
59
0
60
0
  bool isNull = val.isNullOrUndefined();
61
0
  // We only need these if !isNull, in which case we have |cx|.
62
0
  Maybe<JS::Rooted<JSObject *> > object;
63
0
  Maybe<JS::Rooted<JS::Value> > temp;
64
0
  if (!isNull) {
65
0
    MOZ_ASSERT(cx);
66
0
    object.emplace(cx, &val.toObject());
67
0
    temp.emplace(cx);
68
0
  }
69
0
  if (!isNull) {
70
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->done_id, temp.ptr())) {
71
0
      return false;
72
0
    }
73
0
  }
74
0
  if (!isNull && !temp->isUndefined()) {
75
0
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mDone)) {
76
0
      return false;
77
0
    }
78
0
  } else {
79
0
    mDone = false;
80
0
  }
81
0
  mIsAnyMemberPresent = true;
82
0
83
0
  if (!isNull) {
84
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->value_id, temp.ptr())) {
85
0
      return false;
86
0
    }
87
0
  }
88
0
  if (!isNull && !temp->isUndefined()) {
89
0
    if (temp.ref().isObject()) {
90
0
      JS::ForOfIterator iter(cx);
91
0
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
92
0
        return false;
93
0
      }
94
0
      if (!iter.valueIsIterable()) {
95
0
        ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'value' member of IterableKeyAndValueResult");
96
0
        return false;
97
0
      }
98
0
      Sequence<JS::Value> &arr = mValue;
99
0
      JS::Rooted<JS::Value> temp(cx);
100
0
      while (true) {
101
0
        bool done;
102
0
        if (!iter.next(&temp, &done)) {
103
0
          return false;
104
0
        }
105
0
        if (done) {
106
0
          break;
107
0
        }
108
0
        JS::Value* slotPtr = arr.AppendElement(mozilla::fallible);
109
0
        if (!slotPtr) {
110
0
          JS_ReportOutOfMemory(cx);
111
0
          return false;
112
0
        }
113
0
        JS::Value& slot = *slotPtr;
114
0
#ifdef __clang__
115
0
#pragma clang diagnostic push
116
0
#pragma clang diagnostic ignored "-Wunreachable-code"
117
0
#pragma clang diagnostic ignored "-Wunreachable-code-return"
118
0
#endif // __clang__
119
0
        if ((passedToJSImpl) && !CallerSubsumes(temp)) {
120
0
          ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "element of 'value' member of IterableKeyAndValueResult");
121
0
          return false;
122
0
        }
123
0
#ifdef __clang__
124
0
#pragma clang diagnostic pop
125
0
#endif // __clang__
126
0
        slot = temp;
127
0
      }
128
0
    } else {
129
0
      ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'value' member of IterableKeyAndValueResult");
130
0
      return false;
131
0
    }
132
0
  } else {
133
0
    /* Array is already empty; nothing to do */
134
0
  }
135
0
  mIsAnyMemberPresent = true;
136
0
  return true;
137
0
}
138
139
bool
140
IterableKeyAndValueResult::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
141
0
{
142
0
  IterableKeyAndValueResultAtoms* atomsCache = GetAtomCache<IterableKeyAndValueResultAtoms>(cx);
143
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
144
0
    return false;
145
0
  }
146
0
147
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
148
0
  if (!obj) {
149
0
    return false;
150
0
  }
151
0
  rval.set(JS::ObjectValue(*obj));
152
0
153
0
  do {
154
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
155
0
    JS::Rooted<JS::Value> temp(cx);
156
0
    bool const & currentValue = mDone;
157
0
    temp.setBoolean(currentValue);
158
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->done_id, temp, JSPROP_ENUMERATE)) {
159
0
      return false;
160
0
    }
161
0
    break;
162
0
  } while(false);
163
0
164
0
  do {
165
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
166
0
    JS::Rooted<JS::Value> temp(cx);
167
0
    Sequence<JS::Value> const & currentValue = mValue;
168
0
169
0
    uint32_t length = currentValue.Length();
170
0
    JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
171
0
    if (!returnArray) {
172
0
      return false;
173
0
    }
174
0
    // Scope for 'tmp'
175
0
    {
176
0
      JS::Rooted<JS::Value> tmp(cx);
177
0
      for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
178
0
        // Control block to let us common up the JS_DefineElement calls when there
179
0
        // are different ways to succeed at wrapping the object.
180
0
        do {
181
0
          JS::ExposeValueToActiveJS(currentValue[sequenceIdx0]);
182
0
          tmp.set(currentValue[sequenceIdx0]);
183
0
          if (!MaybeWrapValue(cx, &tmp)) {
184
0
            return false;
185
0
          }
186
0
          break;
187
0
        } while (false);
188
0
        if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
189
0
                              JSPROP_ENUMERATE)) {
190
0
          return false;
191
0
        }
192
0
      }
193
0
    }
194
0
    temp.setObject(*returnArray);
195
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->value_id, temp, JSPROP_ENUMERATE)) {
196
0
      return false;
197
0
    }
198
0
    break;
199
0
  } while(false);
200
0
201
0
  return true;
202
0
}
203
204
void
205
IterableKeyAndValueResult::TraceDictionary(JSTracer* trc)
206
0
{
207
0
  DoTraceSequence(trc, mValue);
208
0
}
209
210
namespace binding_detail {
211
} // namespace binding_detail
212
213
214
215
IterableKeyOrValueResult::IterableKeyOrValueResult()
216
  : mValue(JS::UndefinedValue())
217
0
{
218
0
  // Safe to pass a null context if we pass a null value
219
0
  Init(nullptr, JS::NullHandleValue);
220
0
}
221
222
223
bool
224
IterableKeyOrValueResult::InitIds(JSContext* cx, IterableKeyOrValueResultAtoms* atomsCache)
225
0
{
226
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
227
0
228
0
  // Initialize these in reverse order so that any failure leaves the first one
229
0
  // uninitialized.
230
0
  if (!atomsCache->value_id.init(cx, "value") ||
231
0
      !atomsCache->done_id.init(cx, "done")) {
232
0
    return false;
233
0
  }
234
0
  return true;
235
0
}
236
237
bool
238
IterableKeyOrValueResult::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
239
0
{
240
0
  // Passing a null JSContext is OK only if we're initing from null,
241
0
  // Since in that case we will not have to do any property gets
242
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
243
0
  // checkers by static analysis tools
244
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
245
0
  IterableKeyOrValueResultAtoms* atomsCache = nullptr;
246
0
  if (cx) {
247
0
    atomsCache = GetAtomCache<IterableKeyOrValueResultAtoms>(cx);
248
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
249
0
      return false;
250
0
    }
251
0
  }
252
0
253
0
  if (!IsConvertibleToDictionary(val)) {
254
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
255
0
  }
256
0
257
0
  bool isNull = val.isNullOrUndefined();
258
0
  // We only need these if !isNull, in which case we have |cx|.
259
0
  Maybe<JS::Rooted<JSObject *> > object;
260
0
  Maybe<JS::Rooted<JS::Value> > temp;
261
0
  if (!isNull) {
262
0
    MOZ_ASSERT(cx);
263
0
    object.emplace(cx, &val.toObject());
264
0
    temp.emplace(cx);
265
0
  }
266
0
  if (!isNull) {
267
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->done_id, temp.ptr())) {
268
0
      return false;
269
0
    }
270
0
  }
271
0
  if (!isNull && !temp->isUndefined()) {
272
0
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mDone)) {
273
0
      return false;
274
0
    }
275
0
  } else {
276
0
    mDone = false;
277
0
  }
278
0
  mIsAnyMemberPresent = true;
279
0
280
0
  if (!isNull) {
281
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->value_id, temp.ptr())) {
282
0
      return false;
283
0
    }
284
0
  }
285
0
  if (!isNull && !temp->isUndefined()) {
286
0
#ifdef __clang__
287
0
#pragma clang diagnostic push
288
0
#pragma clang diagnostic ignored "-Wunreachable-code"
289
0
#pragma clang diagnostic ignored "-Wunreachable-code-return"
290
0
#endif // __clang__
291
0
    if ((passedToJSImpl) && !CallerSubsumes(temp.ref())) {
292
0
      ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "'value' member of IterableKeyOrValueResult");
293
0
      return false;
294
0
    }
295
0
#ifdef __clang__
296
0
#pragma clang diagnostic pop
297
0
#endif // __clang__
298
0
    mValue = temp.ref();
299
0
  } else {
300
0
    mValue = JS::UndefinedValue();
301
0
  }
302
0
  mIsAnyMemberPresent = true;
303
0
  return true;
304
0
}
305
306
bool
307
IterableKeyOrValueResult::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
308
0
{
309
0
  IterableKeyOrValueResultAtoms* atomsCache = GetAtomCache<IterableKeyOrValueResultAtoms>(cx);
310
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
311
0
    return false;
312
0
  }
313
0
314
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
315
0
  if (!obj) {
316
0
    return false;
317
0
  }
318
0
  rval.set(JS::ObjectValue(*obj));
319
0
320
0
  do {
321
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
322
0
    JS::Rooted<JS::Value> temp(cx);
323
0
    bool const & currentValue = mDone;
324
0
    temp.setBoolean(currentValue);
325
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->done_id, temp, JSPROP_ENUMERATE)) {
326
0
      return false;
327
0
    }
328
0
    break;
329
0
  } while(false);
330
0
331
0
  do {
332
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
333
0
    JS::Rooted<JS::Value> temp(cx);
334
0
    JS::Value const & currentValue = mValue;
335
0
    JS::ExposeValueToActiveJS(currentValue);
336
0
    temp.set(currentValue);
337
0
    if (!MaybeWrapValue(cx, &temp)) {
338
0
      return false;
339
0
    }
340
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->value_id, temp, JSPROP_ENUMERATE)) {
341
0
      return false;
342
0
    }
343
0
    break;
344
0
  } while(false);
345
0
346
0
  return true;
347
0
}
348
349
void
350
IterableKeyOrValueResult::TraceDictionary(JSTracer* trc)
351
0
{
352
0
  JS::UnsafeTraceRoot(trc, &mValue, "IterableKeyOrValueResult.mValue");
353
0
}
354
355
namespace binding_detail {
356
} // namespace binding_detail
357
358
359
} // namespace dom
360
} // namespace mozilla