bool ScriptInterface::ParseJSON(const std::string& string_utf8, JS::MutableHandleValue out) { JSAutoRequest rq(m->m_cx); std::wstring attrsW = wstring_from_utf8(string_utf8); utf16string string(attrsW.begin(), attrsW.end()); if (JS_ParseJSON(m->m_cx, reinterpret_cast<const jschar*>(string.c_str()), (u32)string.size(), out)) return true; LOGERROR("JS_ParseJSON failed!"); if (!JS_IsExceptionPending(m->m_cx)) return false; JS::RootedValue exc(m->m_cx); if (!JS_GetPendingException(m->m_cx, &exc)) return false; JS_ClearPendingException(m->m_cx); // We expect an object of type SyntaxError if (!exc.isObject()) return false; JS::RootedValue rval(m->m_cx); JS::RootedObject excObj(m->m_cx, &exc.toObject()); if (!JS_CallFunctionName(m->m_cx, excObj, "toString", JS::HandleValueArray::empty(), &rval)) return false; std::wstring error; ScriptInterface::FromJSVal(m->m_cx, rval, error); LOGERROR("%s", utf8_from_wstring(error)); return false; }
template<size_t N> inline bool Parse(JSContext *cx, const char (&input)[N], jsval *vp) { AutoInflatedString str(cx); str = input; CHECK(JS_ParseJSON(cx, str.chars(), str.length(), vp)); return true; }
JSObject* ThreadProfile::ToJSObject(JSContext *aCx) { JS::RootedValue val(aCx); std::stringstream ss; JSStreamWriter b(ss); StreamJSObject(b); NS_ConvertUTF8toUTF16 js_string(nsDependentCString(ss.str().c_str())); JS_ParseJSON(aCx, static_cast<const jschar*>(js_string.get()), js_string.Length(), &val); return &val.toObject(); }
template<size_t N> inline bool Error(JSContext *cx, const char (&input)[N]) { AutoInflatedString str(cx); jsval dummy; str = input; CHECK(!JS_ParseJSON(cx, str.chars(), str.length(), &dummy)); JS_ClearPendingException(cx); return true; }
template<size_t N> inline bool TryParse(JSContext *cx, const char (&input)[N], const jsval &expected) { AutoInflatedString str(cx); jsval v; str = input; CHECK(JS_ParseJSON(cx, str.chars(), str.length(), &v)); CHECK_SAME(v, expected); return true; }
NS_IMETHODIMP AutoMounterSetting::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* aData) { if (strcmp(aTopic, MOZSETTINGS_CHANGED) != 0) { return NS_OK; } // Note that this function gets called for any and all settings changes, // so we need to carefully check if we have the one we're interested in. // // The string that we're interested in will be a JSON string that looks like: // {"key":"ums.autoMount","value":true} nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService("@mozilla.org/js/xpc/ContextStack;1"); if (!stack) { ERR("Failed to get JSContextStack"); return NS_OK; } JSContext* cx = stack->GetSafeJSContext(); if (!cx) { ERR("Failed to GetSafeJSContext"); return NS_OK; } nsDependentString dataStr(aData); JS::Value val; if (!JS_ParseJSON(cx, dataStr.get(), dataStr.Length(), &val) || !val.isObject()) { return NS_OK; } JSObject& obj(val.toObject()); JS::Value key; if (!JS_GetProperty(cx, &obj, "key", &key) || !key.isString()) { return NS_OK; } JSBool match; if (!JS_StringEqualsAscii(cx, key.toString(), UMS_MODE, &match) || (match != JS_TRUE)) { return NS_OK; } JS::Value value; if (!JS_GetProperty(cx, &obj, "value", &value) || !value.isInt32()) { return NS_OK; } int32_t mode = value.toInt32(); SetAutoMounterMode(mode); return NS_OK; }
NS_IMETHODIMP nsJSON::DecodeToJSVal(const nsAString &str, JSContext *cx, JS::Value *result) { JSAutoRequest ar(cx); if (!JS_ParseJSON(cx, static_cast<const jschar*>(PromiseFlatString(str).get()), str.Length(), result)) { return NS_ERROR_UNEXPECTED; } return NS_OK; }
JSObject* ThreadProfile::ToJSObject(JSContext *aCx) { JS::RootedValue val(aCx); std::stringstream ss; { // Define a scope to prevent a moving GC during ~JSStreamWriter from // trashing the return value. JSStreamWriter b(ss); StreamJSObject(b); NS_ConvertUTF8toUTF16 js_string(nsDependentCString(ss.str().c_str())); JS_ParseJSON(aCx, static_cast<const char16_t*>(js_string.get()), js_string.Length(), &val); } return &val.toObject(); }
already_AddRefed<Promise> Request::ConsumeBody(ConsumeType aType, ErrorResult& aRv) { nsRefPtr<Promise> promise = Promise::Create(mOwner, aRv); if (aRv.Failed()) { return nullptr; } if (BodyUsed()) { aRv.ThrowTypeError(MSG_REQUEST_BODY_CONSUMED_ERROR); return nullptr; } SetBodyUsed(); // While the spec says to do this asynchronously, all the body constructors // right now only accept bodies whose streams are backed by an in-memory // buffer that can be read without blocking. So I think this is fine. nsCOMPtr<nsIInputStream> stream; mRequest->GetBody(getter_AddRefs(stream)); if (!stream) { aRv = NS_NewByteInputStream(getter_AddRefs(stream), "", 0, NS_ASSIGNMENT_COPY); if (aRv.Failed()) { return nullptr; } } AutoJSAPI api; api.Init(mOwner); JSContext* cx = api.cx(); // We can make this assertion because for now we only support memory backed // structures for the body argument for a Request. MOZ_ASSERT(NS_InputStreamIsBuffered(stream)); nsCString buffer; uint64_t len; aRv = stream->Available(&len); if (aRv.Failed()) { return nullptr; } aRv = NS_ReadInputStreamToString(stream, buffer, len); if (aRv.Failed()) { return nullptr; } buffer.SetLength(len); switch (aType) { case CONSUME_ARRAYBUFFER: { JS::Rooted<JSObject*> arrayBuffer(cx); arrayBuffer = ArrayBuffer::Create(cx, buffer.Length(), reinterpret_cast<const uint8_t*>(buffer.get())); JS::Rooted<JS::Value> val(cx); val.setObjectOrNull(arrayBuffer); promise->MaybeResolve(cx, val); return promise.forget(); } case CONSUME_BLOB: { // XXXnsm it is actually possible to avoid these duplicate allocations // for the Blob case by having the Blob adopt the stream's memory // directly, but I've not added a special case for now. // // This is similar to nsContentUtils::CreateBlobBuffer, but also deals // with worker wrapping. uint32_t blobLen = buffer.Length(); void* blobData = moz_malloc(blobLen); nsRefPtr<File> blob; if (blobData) { memcpy(blobData, buffer.BeginReading(), blobLen); blob = File::CreateMemoryFile(GetParentObject(), blobData, blobLen, NS_ConvertUTF8toUTF16(mMimeType)); } else { aRv = NS_ERROR_OUT_OF_MEMORY; return nullptr; } promise->MaybeResolve(blob); return promise.forget(); } case CONSUME_JSON: { nsString decoded; aRv = DecodeUTF8(buffer, decoded); if (aRv.Failed()) { return nullptr; } JS::Rooted<JS::Value> json(cx); if (!JS_ParseJSON(cx, decoded.get(), decoded.Length(), &json)) { JS::Rooted<JS::Value> exn(cx); if (JS_GetPendingException(cx, &exn)) { JS_ClearPendingException(cx); promise->MaybeReject(cx, exn); } } promise->MaybeResolve(cx, json); return promise.forget(); } case CONSUME_TEXT: { nsString decoded; aRv = DecodeUTF8(buffer, decoded); if (aRv.Failed()) { return nullptr; } promise->MaybeResolve(decoded); return promise.forget(); } } NS_NOTREACHED("Unexpected consume body type"); // Silence warnings. return nullptr; }