Example #1
0
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);
}
Example #5
0
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));
}
Example #8
0
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";
}
Example #10
0
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);
}