Response* Response::create(ScriptState* scriptState, ScriptValue bodyValue, const Dictionary& init, ExceptionState& exceptionState) { v8::Local<v8::Value> body = bodyValue.v8Value(); ScriptValue reader; v8::Isolate* isolate = scriptState->isolate(); ExecutionContext* executionContext = scriptState->executionContext(); OwnPtr<FetchDataConsumerHandle> bodyHandle; String contentType; if (bodyValue.isUndefined() || bodyValue.isNull()) { // Note: The IDL processor cannot handle this situation. See // https://crbug.com/335871. } else if (V8Blob::hasInstance(body, isolate)) { Blob* blob = V8Blob::toImpl(body.As<v8::Object>()); bodyHandle = FetchBlobDataConsumerHandle::create(executionContext, blob->blobDataHandle()); contentType = blob->type(); } else if (V8ArrayBuffer::hasInstance(body, isolate)) { bodyHandle = FetchFormDataConsumerHandle::create(V8ArrayBuffer::toImpl(body.As<v8::Object>())); } else if (V8ArrayBufferView::hasInstance(body, isolate)) { bodyHandle = FetchFormDataConsumerHandle::create(V8ArrayBufferView::toImpl(body.As<v8::Object>())); } else if (V8FormData::hasInstance(body, isolate)) { RefPtr<EncodedFormData> formData = V8FormData::toImpl(body.As<v8::Object>())->encodeMultiPartFormData(); // Here we handle formData->boundary() as a C-style string. See // FormDataEncoder::generateUniqueBoundaryString. contentType = AtomicString("multipart/form-data; boundary=", AtomicString::ConstructFromLiteral) + formData->boundary().data(); bodyHandle = FetchFormDataConsumerHandle::create(executionContext, formData.release()); } else if (RuntimeEnabledFeatures::responseConstructedWithReadableStreamEnabled() && ReadableStreamOperations::isReadableStream(scriptState, bodyValue)) { bodyHandle = ReadableStreamDataConsumerHandle::create(scriptState, bodyValue); reader = ReadableStreamOperations::getReader(scriptState, bodyValue, exceptionState); if (exceptionState.hadException()) { reader = ScriptValue(); bodyHandle = createFetchDataConsumerHandleFromWebHandle(createUnexpectedErrorDataConsumerHandle()); exceptionState.clearException(); } else { bodyHandle = ReadableStreamDataConsumerHandle::create(scriptState, reader); } } else { String string = toUSVString(isolate, body, exceptionState); if (exceptionState.hadException()) return nullptr; bodyHandle = FetchFormDataConsumerHandle::create(string); contentType = "text/plain;charset=UTF-8"; } // TODO(yhirano): Add the URLSearchParams case. Response* response = create(executionContext, bodyHandle.release(), contentType, ResponseInit(init, exceptionState), exceptionState); if (!exceptionState.hadException() && !reader.isEmpty()) { // Add a hidden reference so that the weak persistent in the // ReadableStreamDataConsumerHandle will be valid as long as the // Response is valid. v8::Local<v8::Value> wrapper = toV8(response, scriptState); if (wrapper.IsEmpty()) { exceptionState.throwTypeError("Cannot create a Response wrapper"); return nullptr; } ASSERT(wrapper->IsObject()); V8HiddenValue::setHiddenValue(scriptState, wrapper.As<v8::Object>(), V8HiddenValue::readableStreamReaderInResponse(scriptState->isolate()), reader.v8Value()); } return response; }
bool ReadableStreamOperations::isReadableStreamReader(ScriptState* scriptState, ScriptValue value) { ASSERT(!value.isEmpty()); if (!value.isObject()) return false; v8::Local<v8::Value> args[] = { value.v8Value() }; return V8ScriptRunner::callExtraOrCrash(scriptState, "IsReadableStreamReader", args)->ToBoolean()->Value(); }
void V8XMLHttpRequest::responseTextAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info) { XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(info.Holder()); ExceptionState exceptionState(ExceptionState::GetterContext, "responseText", "XMLHttpRequest", info.Holder(), info.GetIsolate()); ScriptValue text = xmlHttpRequest->responseText(exceptionState); if (exceptionState.throwIfNeeded()) return; if (text.isEmpty()) { v8SetReturnValueString(info, emptyString(), info.GetIsolate()); return; } v8SetReturnValue(info, text.v8Value()); }
void InspectorHeapProfilerAgent::getHeapObjectId(ErrorString* errorString, const String& objectId, String* heapSnapshotObjectId) { InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId); if (injectedScript.isEmpty()) { *errorString = "Inspected context has gone"; return; } ScriptValue value = injectedScript.findObjectById(objectId); ScriptState::Scope scope(injectedScript.scriptState()); if (value.isEmpty() || value.isUndefined()) { *errorString = "Object with given id not found"; return; } unsigned id = ScriptProfiler::getHeapObjectId(value); *heapSnapshotObjectId = String::number(id); }
void Body::readAllFromStream(ScriptState* scriptState) { // With the current loading mechanism, the data is loaded atomically. ASSERT(m_stream->isDraining()); TrackExceptionState es; // FIXME: Implement and use another |read| method that doesn't // need an exception state and V8ArrayBuffer. ScriptValue value = m_stream->read(scriptState, es); ASSERT(!es.hadException()); ASSERT(m_stream->state() == ReadableStream::Closed); ASSERT(!value.isEmpty() && V8ArrayBuffer::hasInstance(value.v8Value(), scriptState->isolate())); DOMArrayBuffer* buffer = V8ArrayBuffer::toImpl(value.v8Value().As<v8::Object>()); didFinishLoadingViaStream(buffer); m_resolver.clear(); m_stream->close(); }
PassRefPtr<TypeBuilder::Runtime::RemoteObject> InjectedScript::wrapTable(const ScriptValue& table, const ScriptValue& columns) const { ASSERT(!isEmpty()); ScriptFunctionCall wrapFunction(injectedScriptObject(), "wrapTable"); wrapFunction.appendArgument(canAccessInspectedWindow()); wrapFunction.appendArgument(table); if (columns.isEmpty()) wrapFunction.appendArgument(false); else wrapFunction.appendArgument(columns); bool hadException = false; ScriptValue r = callFunctionWithEvalEnabled(wrapFunction, hadException); if (hadException) return nullptr; RefPtr<JSONObject> rawResult = toJSONValue(r)->asObject(); return TypeBuilder::Runtime::RemoteObject::runtimeCast(rawResult); }
void V8ErrorEvent::errorAttributeGetterCustom(const v8::FunctionCallbackInfo<v8::Value>& info) { v8::Isolate* isolate = info.GetIsolate(); v8::Local<v8::Value> cachedError = V8HiddenValue::getHiddenValue(ScriptState::current(isolate), info.Holder(), V8HiddenValue::error(isolate)); if (!cachedError.IsEmpty()) { v8SetReturnValue(info, cachedError); return; } ErrorEvent* event = V8ErrorEvent::toImpl(info.Holder()); ScriptState* scriptState = ScriptState::current(isolate); ScriptValue error = event->error(scriptState); if (!error.isEmpty()) setHiddenValueAndReturnValue(scriptState, info, error.v8Value()); else setHiddenValueAndReturnValue(scriptState, info, v8::Null(isolate)); }
ScriptPromise ScriptPromise::cast(const ScriptValue& value) { if (value.isEmpty()) return ScriptPromise(); v8::Local<v8::Value> v8Value(value.v8Value()); v8::Isolate* isolate = value.isolate(); if (V8PromiseCustom::isPromise(v8Value, isolate) || v8Value->IsPromise()) { return ScriptPromise(value.scriptState(), v8Value); } if (RuntimeEnabledFeatures::scriptPromiseOnV8PromiseEnabled()) { v8::Local<v8::Promise::Resolver> resolver = v8::Promise::Resolver::New(isolate); if (resolver.IsEmpty()) { // The Promise constructor may return an empty value, for example // when the stack is exhausted. return ScriptPromise(); } resolver->Resolve(v8Value); return ScriptPromise(value.scriptState(), resolver->GetPromise()); } return ScriptPromise(value.scriptState(), V8PromiseCustom::toPromise(v8Value, isolate)); }
void InspectorHeapProfilerAgent::getObjectByHeapObjectId(ErrorString* error, const String& heapSnapshotObjectId, const String* objectGroup, RefPtr<TypeBuilder::Runtime::RemoteObject>& result) { bool ok; unsigned id = heapSnapshotObjectId.toUInt(&ok); if (!ok) { *error = "Invalid heap snapshot object id"; return; } ScriptValue heapObject = ScriptProfiler::objectByHeapObjectId(id); if (heapObject.isEmpty()) { *error = "Object is not available"; return; } InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(heapObject.scriptState()); if (injectedScript.isEmpty()) { *error = "Object is not available. Inspected context is gone"; return; } result = injectedScript.wrapObject(heapObject, objectGroup ? *objectGroup : ""); if (!result) *error = "Failed to wrap object"; }
BodyStreamBuffer::BodyStreamBuffer(ScriptState* scriptState, BytesConsumer* consumer) : UnderlyingSourceBase(scriptState), m_scriptState(scriptState), m_consumer(consumer), m_madeFromReadableStream(false) { v8::Local<v8::Value> bodyValue = toV8(this, scriptState); DCHECK(!bodyValue.IsEmpty()); DCHECK(bodyValue->IsObject()); v8::Local<v8::Object> body = bodyValue.As<v8::Object>(); ScriptValue readableStream = ReadableStreamOperations::createReadableStream( scriptState, this, ReadableStreamOperations::createCountQueuingStrategy(scriptState, 0)); DCHECK(!readableStream.isEmpty()); V8HiddenValue::setHiddenValue( scriptState, body, V8HiddenValue::internalBodyStream(scriptState->isolate()), readableStream.v8Value()); m_consumer->setClient(this); onStateChange(); }
IDBRequest* IDBObjectStore::put(ScriptState* scriptState, WebIDBPutMode putMode, IDBAny* source, const ScriptValue& value, IDBKey* key, ExceptionState& exceptionState) { if (isDeleted()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectStoreDeletedErrorMessage); return nullptr; } if (m_transaction->isFinished() || m_transaction->isFinishing()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionFinishedErrorMessage); return nullptr; } if (!m_transaction->isActive()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionInactiveErrorMessage); return nullptr; } if (m_transaction->isReadOnly()) { exceptionState.throwDOMException(ReadOnlyError, IDBDatabase::transactionReadOnlyErrorMessage); return nullptr; } Vector<WebBlobInfo> blobInfo; RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValueFactory::instance().create(scriptState->isolate(), value, &blobInfo, exceptionState); if (exceptionState.hadException()) return nullptr; // Keys that need to be extracted must be taken from a clone so that // side effects (i.e. getters) are not triggered. Construct the // clone lazily since the operation may be expensive. ScriptValue clone; const IDBKeyPath& keyPath = m_metadata.keyPath; const bool usesInLineKeys = !keyPath.isNull(); const bool hasKeyGenerator = autoIncrement(); if (putMode != WebIDBPutModeCursorUpdate && usesInLineKeys && key) { exceptionState.throwDOMException(DataError, "The object store uses in-line keys and the key parameter was provided."); return nullptr; } // This test logically belongs in IDBCursor, but must operate on the cloned value. if (putMode == WebIDBPutModeCursorUpdate && usesInLineKeys) { ASSERT(key); if (clone.isEmpty()) clone = deserializeScriptValue(scriptState, serializedValue.get(), &blobInfo); IDBKey* keyPathKey = ScriptValue::to<IDBKey*>(scriptState->isolate(), clone, exceptionState, keyPath); if (exceptionState.hadException()) return nullptr; if (!keyPathKey || !keyPathKey->isEqual(key)) { exceptionState.throwDOMException(DataError, "The effective object store of this cursor uses in-line keys and evaluating the key path of the value parameter results in a different value than the cursor's effective key."); return nullptr; } } if (!usesInLineKeys && !hasKeyGenerator && !key) { exceptionState.throwDOMException(DataError, "The object store uses out-of-line keys and has no key generator and the key parameter was not provided."); return nullptr; } if (usesInLineKeys) { if (clone.isEmpty()) clone = deserializeScriptValue(scriptState, serializedValue.get(), &blobInfo); IDBKey* keyPathKey = ScriptValue::to<IDBKey*>(scriptState->isolate(), clone, exceptionState, keyPath); if (exceptionState.hadException()) return nullptr; if (keyPathKey && !keyPathKey->isValid()) { exceptionState.throwDOMException(DataError, "Evaluating the object store's key path yielded a value that is not a valid key."); return nullptr; } if (!hasKeyGenerator && !keyPathKey) { exceptionState.throwDOMException(DataError, "Evaluating the object store's key path did not yield a value."); return nullptr; } if (hasKeyGenerator && !keyPathKey) { if (!canInjectIDBKeyIntoScriptValue(scriptState->isolate(), clone, keyPath)) { exceptionState.throwDOMException(DataError, "A generated key could not be inserted into the value."); return nullptr; } } if (keyPathKey) key = keyPathKey; } if (key && !key->isValid()) { exceptionState.throwDOMException(DataError, IDBDatabase::notValidKeyErrorMessage); return nullptr; } if (!backendDB()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databaseClosedErrorMessage); return nullptr; } Vector<int64_t> indexIds; HeapVector<IndexKeys> indexKeys; for (const auto& it : m_metadata.indexes) { if (clone.isEmpty()) clone = deserializeScriptValue(scriptState, serializedValue.get(), &blobInfo); IndexKeys keys; generateIndexKeysForValue(scriptState->isolate(), it.value, clone, &keys); indexIds.append(it.key); indexKeys.append(keys); } IDBRequest* request = IDBRequest::create(scriptState, source, m_transaction.get()); Vector<char> wireBytes; serializedValue->toWireBytes(wireBytes); RefPtr<SharedBuffer> valueBuffer = SharedBuffer::adoptVector(wireBytes); backendDB()->put(m_transaction->id(), id(), WebData(valueBuffer), blobInfo, key, static_cast<WebIDBPutMode>(putMode), WebIDBCallbacksImpl::create(request).leakPtr(), indexIds, indexKeys); return request; }
void V8HTMLCanvasElement::getContextMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) { v8::Handle<v8::Object> holder = info.Holder(); v8::Isolate* isolate = info.GetIsolate(); HTMLCanvasElement* impl = V8HTMLCanvasElement::toNative(holder); TOSTRING_VOID(V8StringResource<>, contextIdResource, info[0]); String contextId = contextIdResource; RefPtr<CanvasContextAttributes> attributes; if (contextId == "webgl" || contextId == "experimental-webgl") { RefPtr<WebGLContextAttributes> webGLAttributes = WebGLContextAttributes::create(); if (info.Length() > 1 && info[1]->IsObject()) { v8::Handle<v8::Object> jsAttributes = info[1]->ToObject(); v8::Handle<v8::String> alpha = v8AtomicString(isolate, "alpha"); if (jsAttributes->Has(alpha) && !isUndefinedOrNull(jsAttributes->Get(alpha))) webGLAttributes->setAlpha(jsAttributes->Get(alpha)->BooleanValue()); v8::Handle<v8::String> depth = v8AtomicString(isolate, "depth"); if (jsAttributes->Has(depth) && !isUndefinedOrNull(jsAttributes->Get(depth))) webGLAttributes->setDepth(jsAttributes->Get(depth)->BooleanValue()); v8::Handle<v8::String> stencil = v8AtomicString(isolate, "stencil"); if (jsAttributes->Has(stencil) && !isUndefinedOrNull(jsAttributes->Get(stencil))) webGLAttributes->setStencil(jsAttributes->Get(stencil)->BooleanValue()); v8::Handle<v8::String> antialias = v8AtomicString(isolate, "antialias"); if (jsAttributes->Has(antialias) && !isUndefinedOrNull(jsAttributes->Get(antialias))) webGLAttributes->setAntialias(jsAttributes->Get(antialias)->BooleanValue()); v8::Handle<v8::String> premultipliedAlpha = v8AtomicString(isolate, "premultipliedAlpha"); if (jsAttributes->Has(premultipliedAlpha) && !isUndefinedOrNull(jsAttributes->Get(premultipliedAlpha))) webGLAttributes->setPremultipliedAlpha(jsAttributes->Get(premultipliedAlpha)->BooleanValue()); v8::Handle<v8::String> preserveDrawingBuffer = v8AtomicString(isolate, "preserveDrawingBuffer"); if (jsAttributes->Has(preserveDrawingBuffer) && !isUndefinedOrNull(jsAttributes->Get(preserveDrawingBuffer))) webGLAttributes->setPreserveDrawingBuffer(jsAttributes->Get(preserveDrawingBuffer)->BooleanValue()); v8::Handle<v8::String> failIfMajorPerformanceCaveat = v8AtomicString(isolate, "failIfMajorPerformanceCaveat"); if (jsAttributes->Has(failIfMajorPerformanceCaveat) && !isUndefinedOrNull(jsAttributes->Get(failIfMajorPerformanceCaveat))) webGLAttributes->setFailIfMajorPerformanceCaveat(jsAttributes->Get(failIfMajorPerformanceCaveat)->BooleanValue()); } attributes = webGLAttributes; } else { RefPtr<Canvas2DContextAttributes> canvas2DAttributes = Canvas2DContextAttributes::create(); if (info.Length() > 1 && info[1]->IsObject()) { v8::Handle<v8::Object> jsAttributes = info[1]->ToObject(); v8::Handle<v8::String> alpha = v8AtomicString(isolate, "alpha"); if (jsAttributes->Has(alpha) && !isUndefinedOrNull(jsAttributes->Get(alpha))) canvas2DAttributes->setAlpha(jsAttributes->Get(alpha)->BooleanValue()); } attributes = canvas2DAttributes; } CanvasRenderingContext* result = impl->getContext(contextId, attributes.get()); if (!result) { v8SetReturnValueNull(info); return; } if (result->is2d()) { v8::Handle<v8::Value> v8Result = toV8(toCanvasRenderingContext2D(result), info.Holder(), info.GetIsolate()); if (InspectorInstrumentation::canvasAgentEnabled(&impl->document())) { ScriptState* scriptState = ScriptState::current(isolate); ScriptValue context(scriptState, v8Result); ScriptValue wrapped = InspectorInstrumentation::wrapCanvas2DRenderingContextForInstrumentation(&impl->document(), context); if (!wrapped.isEmpty()) { v8SetReturnValue(info, wrapped.v8Value()); return; } } v8SetReturnValue(info, v8Result); return; } if (result->is3d()) { v8::Handle<v8::Value> v8Result = toV8(toWebGLRenderingContext(result), info.Holder(), info.GetIsolate()); if (InspectorInstrumentation::canvasAgentEnabled(&impl->document())) { ScriptState* scriptState = ScriptState::current(isolate); ScriptValue glContext(scriptState, v8Result); ScriptValue wrapped = InspectorInstrumentation::wrapWebGLRenderingContextForInstrumentation(&impl->document(), glContext); if (!wrapped.isEmpty()) { v8SetReturnValue(info, wrapped.v8Value()); return; } } v8SetReturnValue(info, v8Result); return; } ASSERT_NOT_REACHED(); v8SetReturnValueNull(info); }