Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/KeyIdsInitDataBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM KeyIdsInitData.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "AtomList.h"
4
#include "KeyIdsInitDataBinding.h"
5
#include "mozilla/OwningNonNull.h"
6
#include "mozilla/dom/BindingUtils.h"
7
#include "mozilla/dom/NonRefcountedDOMObject.h"
8
#include "mozilla/dom/ScriptSettings.h"
9
#include "mozilla/dom/SimpleGlobalObject.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
KeyIdsInitData::KeyIdsInitData()
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
27
bool
28
KeyIdsInitData::InitIds(JSContext* cx, KeyIdsInitDataAtoms* atomsCache)
29
0
{
30
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
31
0
32
0
  // Initialize these in reverse order so that any failure leaves the first one
33
0
  // uninitialized.
34
0
  if (!atomsCache->kids_id.init(cx, "kids")) {
35
0
    return false;
36
0
  }
37
0
  return true;
38
0
}
39
40
bool
41
KeyIdsInitData::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
  KeyIdsInitDataAtoms* atomsCache = nullptr;
49
0
  if (cx) {
50
0
    atomsCache = GetAtomCache<KeyIdsInitDataAtoms>(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->kids_id, temp.ptr())) {
71
0
      return false;
72
0
    }
73
0
  }
74
0
  if (!isNull && !temp->isUndefined()) {
75
0
    if (temp.ref().isObject()) {
76
0
      JS::ForOfIterator iter(cx);
77
0
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
78
0
        return false;
79
0
      }
80
0
      if (!iter.valueIsIterable()) {
81
0
        ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'kids' member of KeyIdsInitData");
82
0
        return false;
83
0
      }
84
0
      Sequence<nsString> &arr = mKids;
85
0
      JS::Rooted<JS::Value> temp(cx);
86
0
      while (true) {
87
0
        bool done;
88
0
        if (!iter.next(&temp, &done)) {
89
0
          return false;
90
0
        }
91
0
        if (done) {
92
0
          break;
93
0
        }
94
0
        nsString* slotPtr = arr.AppendElement(mozilla::fallible);
95
0
        if (!slotPtr) {
96
0
          JS_ReportOutOfMemory(cx);
97
0
          return false;
98
0
        }
99
0
        nsString& slot = *slotPtr;
100
0
        if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
101
0
          return false;
102
0
        }
103
0
      }
104
0
    } else {
105
0
      ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'kids' member of KeyIdsInitData");
106
0
      return false;
107
0
    }
108
0
    mIsAnyMemberPresent = true;
109
0
  } else if (cx) {
110
0
    // Don't error out if we have no cx.  In that
111
0
    // situation the caller is default-constructing us and we'll
112
0
    // just assume they know what they're doing.
113
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
114
0
                             "'kids' member of KeyIdsInitData");
115
0
  }
116
0
  return true;
117
0
}
118
119
bool
120
KeyIdsInitData::Init(const nsAString& aJSON)
121
0
{
122
0
  AutoJSAPI jsapi;
123
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
124
0
  if (!cleanGlobal) {
125
0
    return false;
126
0
  }
127
0
  if (!jsapi.Init(cleanGlobal)) {
128
0
    return false;
129
0
  }
130
0
  JSContext* cx = jsapi.cx();
131
0
  JS::Rooted<JS::Value> json(cx);
132
0
  bool ok = ParseJSON(cx, aJSON, &json);
133
0
  NS_ENSURE_TRUE(ok, false);
134
0
  return Init(cx, json);
135
0
}
136
137
bool
138
KeyIdsInitData::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
139
0
{
140
0
  KeyIdsInitDataAtoms* atomsCache = GetAtomCache<KeyIdsInitDataAtoms>(cx);
141
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
142
0
    return false;
143
0
  }
144
0
145
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
146
0
  if (!obj) {
147
0
    return false;
148
0
  }
149
0
  rval.set(JS::ObjectValue(*obj));
150
0
151
0
  do {
152
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
153
0
    JS::Rooted<JS::Value> temp(cx);
154
0
    Sequence<nsString> const & currentValue = mKids;
155
0
156
0
    uint32_t length = currentValue.Length();
157
0
    JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
158
0
    if (!returnArray) {
159
0
      return false;
160
0
    }
161
0
    // Scope for 'tmp'
162
0
    {
163
0
      JS::Rooted<JS::Value> tmp(cx);
164
0
      for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
165
0
        // Control block to let us common up the JS_DefineElement calls when there
166
0
        // are different ways to succeed at wrapping the object.
167
0
        do {
168
0
          if (!xpc::NonVoidStringToJsval(cx, currentValue[sequenceIdx0], &tmp)) {
169
0
            return false;
170
0
          }
171
0
          break;
172
0
        } while (false);
173
0
        if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
174
0
                              JSPROP_ENUMERATE)) {
175
0
          return false;
176
0
        }
177
0
      }
178
0
    }
179
0
    temp.setObject(*returnArray);
180
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->kids_id, temp, JSPROP_ENUMERATE)) {
181
0
      return false;
182
0
    }
183
0
    break;
184
0
  } while(false);
185
0
186
0
  return true;
187
0
}
188
189
bool
190
KeyIdsInitData::ToJSON(nsAString& aJSON) const
191
0
{
192
0
  AutoJSAPI jsapi;
193
0
  jsapi.Init();
194
0
  JSContext *cx = jsapi.cx();
195
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
196
0
  // because we'll only be creating objects, in ways that have no
197
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
198
0
  // which likewise guarantees no side-effects for the sorts of
199
0
  // things we will pass it.
200
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
201
0
  JS::Rooted<JS::Value> val(cx);
202
0
  if (!ToObjectInternal(cx, &val)) {
203
0
    return false;
204
0
  }
205
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
206
0
  return StringifyToJSON(cx, obj, aJSON);
207
0
}
208
209
void
210
KeyIdsInitData::TraceDictionary(JSTracer* trc)
211
0
{
212
0
}
213
214
KeyIdsInitData&
215
KeyIdsInitData::operator=(const KeyIdsInitData& aOther)
216
0
{
217
0
  DictionaryBase::operator=(aOther);
218
0
  mKids = aOther.mKids;
219
0
  return *this;
220
0
}
221
222
namespace binding_detail {
223
} // namespace binding_detail
224
225
226
} // namespace dom
227
} // namespace mozilla