Exemple #1
0
void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode)
{
    if (isExecutionForbidden())
        return;

    Deprecated::ScriptValue exception;
    evaluate(sourceCode, &exception);
    if (exception.jsValue()) {
        JSLockHolder lock(vm());
        reportException(m_workerGlobalScopeWrapper->globalExec(), exception.jsValue());
    }
}
static JSC::JSValue handleInitMessageEvent(JSMessageEvent* jsEvent, JSC::ExecState* exec)
{
    const String& typeArg = exec->argument(0).toString(exec)->value(exec);
    bool canBubbleArg = exec->argument(1).toBoolean(exec);
    bool cancelableArg = exec->argument(2).toBoolean(exec);
    const String originArg = exec->argument(4).toString(exec)->value(exec);
    const String lastEventIdArg = exec->argument(5).toString(exec)->value(exec);
    DOMWindow* sourceArg = toDOMWindow(exec->argument(6));
    std::unique_ptr<MessagePortArray> messagePorts;
    OwnPtr<ArrayBufferArray> arrayBuffers;
    if (!exec->argument(7).isUndefinedOrNull()) {
        messagePorts = std::make_unique<MessagePortArray>();
        arrayBuffers = adoptPtr(new ArrayBufferArray);
        fillMessagePortArray(exec, exec->argument(7), *messagePorts, *arrayBuffers);
        if (exec->hadException())
            return jsUndefined();
    }
    Deprecated::ScriptValue dataArg = Deprecated::ScriptValue(exec->vm(), exec->argument(3));
    if (exec->hadException())
        return jsUndefined();

    MessageEvent& event = jsEvent->impl();
    event.initMessageEvent(typeArg, canBubbleArg, cancelableArg, dataArg, originArg, lastEventIdArg, sourceArg, WTF::move(messagePorts));
    jsEvent->m_data.set(exec->vm(), jsEvent, dataArg.jsValue());
    return jsUndefined();
}
bool injectIDBKeyIntoScriptValue(DOMRequestState* requestState, PassRefPtr<IDBKey> key, Deprecated::ScriptValue& value, const IDBKeyPath& keyPath)
{
    LOG(StorageAPI, "injectIDBKeyIntoScriptValue");

    ASSERT(keyPath.type() == IndexedDB::KeyPathType::String);

    Vector<String> keyPathElements;
    IDBKeyPathParseError error;
    IDBParseKeyPath(keyPath.string(), keyPathElements, error);
    ASSERT(error == IDBKeyPathParseError::None);

    if (keyPathElements.isEmpty())
        return false;

    ExecState* exec = requestState->exec();

    JSValue parent = ensureNthValueOnKeyPath(exec, value.jsValue(), keyPathElements, keyPathElements.size() - 1);
    if (parent.isUndefined())
        return false;

    if (!set(exec, parent, keyPathElements.last(), idbKeyToJSValue(exec, exec->lexicalGlobalObject(), key.get())))
        return false;

    return true;
}
Exemple #4
0
RefPtr<WebCore::IDBRequest> IDBCursor::update(JSC::ExecState& exec, Deprecated::ScriptValue& value, ExceptionCode& ec)
{
    LOG(IndexedDB, "IDBCursor::update");

    if (sourcesDeleted()) {
        ec = IDBDatabaseException::InvalidStateError;
        return nullptr;
    }

    if (!transaction().isActive()) {
        ec = IDBDatabaseException::TransactionInactiveError;
        return nullptr;
    }

    if (transaction().isReadOnly()) {
        ec = IDBDatabaseException::ReadOnlyError;
        return nullptr;
    }

    if (!m_gotValue) {
        ec = IDBDatabaseException::InvalidStateError;
        return nullptr;
    }

    if (isKeyCursor()) {
        ec = IDBDatabaseException::InvalidStateError;
        return nullptr;
    }

    return effectiveObjectStore().put(exec, value.jsValue(), m_deprecatedCurrentPrimaryKey.jsValue(), ec);
}
RefPtr<WebCore::IDBRequest> IDBCursor::update(JSC::ExecState& exec, Deprecated::ScriptValue& value, ExceptionCodeWithMessage& ec)
{
    LOG(IndexedDB, "IDBCursor::update");

    if (sourcesDeleted()) {
        ec.code = IDBDatabaseException::InvalidStateError;
        return nullptr;
    }

    if (!transaction().isActive()) {
        ec.code = IDBDatabaseException::TransactionInactiveError;
        ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The transaction is inactive or finished.");
        return nullptr;
    }

    if (transaction().isReadOnly()) {
        ec.code = IDBDatabaseException::ReadOnlyError;
        ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The record may not be updated inside a read-only transaction.");
        return nullptr;
    }

    if (!m_gotValue) {
        ec.code = IDBDatabaseException::InvalidStateError;
        return nullptr;
    }

    if (isKeyCursor()) {
        ec.code = IDBDatabaseException::InvalidStateError;
        ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The cursor is a key cursor.");
        return nullptr;
    }

    auto& objectStore = effectiveObjectStore();
    auto& keyPath = objectStore.info().keyPath();
    const bool usesInLineKeys = !keyPath.isNull();
    if (usesInLineKeys) {
        RefPtr<IDBKey> keyPathKey = maybeCreateIDBKeyFromScriptValueAndKeyPath(exec, value, keyPath);
        IDBKeyData keyPathKeyData(keyPathKey.get());
        if (!keyPathKey || keyPathKeyData != m_currentPrimaryKeyData) {
            ec.code = IDBDatabaseException::DataError;
            ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': 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;
        }
    }

    auto request = effectiveObjectStore().putForCursorUpdate(exec, value.jsValue(), m_deprecatedCurrentPrimaryKey.jsValue(), ec);
    if (ec.code)
        return nullptr;

    ASSERT(request);
    request->setSource(*this);
    return request;
}
JSValue JSCommandLineAPIHost::inspectedObject(ExecState* exec)
{
    CommandLineAPIHost::InspectableObject* object = impl().inspectedObject();
    if (!object)
        return jsUndefined();

    JSLockHolder lock(exec);
    Deprecated::ScriptValue scriptValue = object->get(exec);
    if (scriptValue.hasNoValue())
        return jsUndefined();

    return scriptValue.jsValue();
}
static RefPtr<IDBKey> internalCreateIDBKeyFromScriptValueAndKeyPath(ExecState* exec, const Deprecated::ScriptValue& value, const String& keyPath)
{
    Vector<String> keyPathElements;
    IDBKeyPathParseError error;
    IDBParseKeyPath(keyPath, keyPathElements, error);
    ASSERT(error == IDBKeyPathParseErrorNone);

    JSValue jsValue = value.jsValue();
    jsValue = getNthValueOnKeyPath(exec, jsValue, keyPathElements, keyPathElements.size());
    if (jsValue.isUndefined())
        return nullptr;
    return createIDBKeyFromValue(exec, jsValue);
}
bool canInjectIDBKeyIntoScriptValue(DOMRequestState* requestState, const Deprecated::ScriptValue& scriptValue, const IDBKeyPath& keyPath)
{
    LOG(StorageAPI, "canInjectIDBKeyIntoScriptValue");

    ASSERT(keyPath.type() == IDBKeyPath::StringType);
    Vector<String> keyPathElements;
    IDBKeyPathParseError error;
    IDBParseKeyPath(keyPath.string(), keyPathElements, error);
    ASSERT(error == IDBKeyPathParseErrorNone);

    if (!keyPathElements.size())
        return false;

    JSC::ExecState* exec = requestState->exec();
    return canInjectNthValueOnKeyPath(exec, scriptValue.jsValue(), keyPathElements, keyPathElements.size() - 1);
}
JSValue JSCommandLineAPIHost::inspectedObject(ExecState* exec)
{
    if (exec->argumentCount() < 1)
        return jsUndefined();

    CommandLineAPIHost::InspectableObject* object = impl().inspectedObject(exec->uncheckedArgument(0).toInt32(exec));
    if (!object)
        return jsUndefined();

    JSLockHolder lock(exec);
    Deprecated::ScriptValue scriptValue = object->get(exec);
    if (scriptValue.hasNoValue())
        return jsUndefined();

    return scriptValue.jsValue();
}
JSValue JSMessageEvent::data(ExecState* exec) const
{
    if (JSValue cachedValue = m_data.get())
        return cachedValue;

    MessageEvent& event = impl();
    JSValue result;
    switch (event.dataType()) {
    case MessageEvent::DataTypeScriptValue: {
        Deprecated::ScriptValue scriptValue = event.dataAsScriptValue();
        if (scriptValue.hasNoValue())
            result = jsNull();
        else
            result = scriptValue.jsValue();
        break;
    }

    case MessageEvent::DataTypeSerializedScriptValue:
        if (RefPtr<SerializedScriptValue> serializedValue = event.dataAsSerializedScriptValue()) {
            MessagePortArray ports = impl().ports();
            // FIXME: Why does this suppress exceptions?
            result = serializedValue->deserialize(exec, globalObject(), &ports, NonThrowing);
        } else
            result = jsNull();
        break;

    case MessageEvent::DataTypeString:
        result = jsStringWithCache(exec, event.dataAsString());
        break;

    case MessageEvent::DataTypeBlob:
        result = toJS(exec, globalObject(), event.dataAsBlob());
        break;

    case MessageEvent::DataTypeArrayBuffer:
        result = toJS(exec, globalObject(), event.dataAsArrayBuffer());
        break;
    }

    // Save the result so we don't have to deserialize the value again.
    const_cast<JSMessageEvent*>(this)->m_data.set(exec->vm(), this, result);
    return result;
}
Exemple #11
0
void WorkerScriptController::setException(const Deprecated::ScriptValue& exception)
{
    m_workerGlobalScopeWrapper->globalExec()->vm().throwException(m_workerGlobalScopeWrapper->globalExec(), exception.jsValue());
}
Exemple #12
0
RefPtr<WebCore::IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCode& ec)
{
    return deleteFunction(context, key.jsValue(), ec);
}
RefPtr<IDBKey> scriptValueToIDBKey(DOMRequestState* requestState, const Deprecated::ScriptValue& scriptValue)
{
    ExecState* exec = requestState->exec();
    return createIDBKeyFromValue(exec, scriptValue.jsValue());
}
void ScriptCallArgumentHandler::appendArgument(const Deprecated::ScriptValue& argument)
{
    m_arguments.append(argument.jsValue());
}
PassRefPtr<IDBRequest> IDBObjectStore::put(IDBDatabaseBackend::PutMode putMode, PassRefPtr<IDBAny> source, JSC::ExecState* state, Deprecated::ScriptValue& value, PassRefPtr<IDBKey> prpKey, ExceptionCode& ec)
{
    RefPtr<IDBKey> key = prpKey;
    if (m_deleted) {
        ec = IDBDatabaseException::InvalidStateError;
        return nullptr;
    }
    if (!m_transaction->isActive()) {
        ec = IDBDatabaseException::TransactionInactiveError;
        return nullptr;
    }
    if (m_transaction->isReadOnly()) {
        ec = IDBDatabaseException::ReadOnlyError;
        return nullptr;
    }

    RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(state, value.jsValue(), nullptr, nullptr);
    if (state->hadException())
        return nullptr;

    if (serializedValue->hasBlobURLs()) {
        // FIXME: Add Blob/File/FileList support
        ec = IDBDatabaseException::DataCloneError;
        return nullptr;
    }

    const IDBKeyPath& keyPath = m_metadata.keyPath;
    const bool usesInLineKeys = !keyPath.isNull();
    const bool hasKeyGenerator = autoIncrement();

    ScriptExecutionContext* context = scriptExecutionContextFromExecState(state);
    DOMRequestState requestState(context);

    if (putMode != IDBDatabaseBackend::CursorUpdate && usesInLineKeys && key) {
        ec = IDBDatabaseException::DataError;
        return nullptr;
    }
    if (!usesInLineKeys && !hasKeyGenerator && !key) {
        ec = IDBDatabaseException::DataError;
        return nullptr;
    }
    if (usesInLineKeys) {
        RefPtr<IDBKey> keyPathKey = createIDBKeyFromScriptValueAndKeyPath(requestState.exec(), value, keyPath);
        if (keyPathKey && !keyPathKey->isValid()) {
            ec = IDBDatabaseException::DataError;
            return nullptr;
        }
        if (!hasKeyGenerator && !keyPathKey) {
            ec = IDBDatabaseException::DataError;
            return nullptr;
        }
        if (hasKeyGenerator && !keyPathKey) {
            if (!canInjectIDBKeyIntoScriptValue(&requestState, value, keyPath)) {
                ec = IDBDatabaseException::DataError;
                return nullptr;
            }
        }
        if (keyPathKey)
            key = keyPathKey;
    }
    if (key && !key->isValid()) {
        ec = IDBDatabaseException::DataError;
        return nullptr;
    }

    Vector<int64_t> indexIds;
    Vector<IndexKeys> indexKeys;
    for (auto& index : m_metadata.indexes) {
        Vector<IDBKeyData> keyDatas;
        generateIndexKeysForValue(requestState.exec(), index.value, value, keyDatas);
        indexIds.append(index.key);

        // FIXME: Much of the Indexed DB code needs to use IDBKeyData directly to avoid wasteful conversions like this.
        Vector<RefPtr<IDBKey>> keys;
        for (auto& keyData : keyDatas) {
            RefPtr<IDBKey> key = keyData.maybeCreateIDBKey();
            if (key)
                keys.append(key.release());
        }
        indexKeys.append(keys);
    }

    RefPtr<IDBRequest> request = IDBRequest::create(context, source, m_transaction.get());
    Vector<uint8_t> valueBytes = serializedValue->toWireBytes();
    // This is a hack to account for disagreements about whether SerializedScriptValue should deal in Vector<uint8_t> or Vector<char>.
    // See https://lists.webkit.org/pipermail/webkit-dev/2013-February/023682.html
    Vector<char>* valueBytesSigned = reinterpret_cast<Vector<char>*>(&valueBytes);
    RefPtr<SharedBuffer> valueBuffer = SharedBuffer::adoptVector(*valueBytesSigned);
    backendDB()->put(m_transaction->id(), id(), valueBuffer, key.release(), static_cast<IDBDatabaseBackend::PutMode>(putMode), request, indexIds, indexKeys);
    return request.release();
}