static JSC::JSValue handleInitMessageEvent(JSMessageEvent* jsEvent, JSC::ExecState& state) { const String& typeArg = state.argument(0).toString(&state)->value(&state); bool canBubbleArg = state.argument(1).toBoolean(&state); bool cancelableArg = state.argument(2).toBoolean(&state); const String originArg = valueToUSVString(&state, state.argument(4)); const String lastEventIdArg = state.argument(5).toString(&state)->value(&state); DOMWindow* sourceArg = JSDOMWindow::toWrapped(state, state.argument(6)); std::unique_ptr<MessagePortArray> messagePorts; std::unique_ptr<ArrayBufferArray> arrayBuffers; if (!state.argument(7).isUndefinedOrNull()) { messagePorts = std::make_unique<MessagePortArray>(); arrayBuffers = std::make_unique<ArrayBufferArray>(); fillMessagePortArray(state, state.argument(7), *messagePorts, *arrayBuffers); if (state.hadException()) return jsUndefined(); } Deprecated::ScriptValue dataArg(state.vm(), state.argument(3)); if (state.hadException()) return jsUndefined(); MessageEvent& event = jsEvent->wrapped(); event.initMessageEvent(typeArg, canBubbleArg, cancelableArg, dataArg, originArg, lastEventIdArg, sourceArg, WTFMove(messagePorts)); jsEvent->m_data.set(state.vm(), jsEvent, dataArg.jsValue()); return jsUndefined(); }
JSValue JSDocument::getCSSCanvasContext(JSC::ExecState& state) { VM& vm = state.vm(); auto scope = DECLARE_THROW_SCOPE(vm); if (UNLIKELY(state.argumentCount() < 4)) return throwException(&state, scope, createNotEnoughArgumentsError(&state)); auto contextId = state.uncheckedArgument(0).toWTFString(&state); if (UNLIKELY(state.hadException())) return jsUndefined(); auto name = state.uncheckedArgument(1).toWTFString(&state); if (UNLIKELY(state.hadException())) return jsUndefined(); auto width = convert<int32_t>(state, state.uncheckedArgument(2), NormalConversion); if (UNLIKELY(state.hadException())) return jsUndefined(); auto height = convert<int32_t>(state, state.uncheckedArgument(3), NormalConversion); if (UNLIKELY(state.hadException())) return jsUndefined(); auto* context = wrapped().getCSSCanvasContext(WTFMove(contextId), WTFMove(name), WTFMove(width), WTFMove(height)); if (!context) return jsNull(); #if ENABLE(WEBGL) if (is<WebGLRenderingContextBase>(*context)) return toJS(&state, globalObject(), downcast<WebGLRenderingContextBase>(*context)); #endif return toJS(&state, globalObject(), downcast<CanvasRenderingContext2D>(*context)); }
void fillMessagePortArray(JSC::ExecState& state, JSC::JSValue value, MessagePortArray& portArray, ArrayBufferArray& arrayBuffers) { // Convert from the passed-in JS array-like object to a MessagePortArray. // Also validates the elements per sections 4.1.13 and 4.1.15 of the WebIDL spec and section 8.3.3 of the HTML5 spec. if (value.isUndefinedOrNull()) { portArray.resize(0); arrayBuffers.resize(0); return; } // Validation of sequence types, per WebIDL spec 4.1.13. unsigned length = 0; JSObject* object = toJSSequence(state, value, length); if (state.hadException()) return; for (unsigned i = 0 ; i < length; ++i) { JSValue value = object->get(&state, i); if (state.hadException()) return; // Validation of non-null objects, per HTML5 spec 10.3.3. if (value.isUndefinedOrNull()) { setDOMException(&state, INVALID_STATE_ERR); return; } // Validation of Objects implementing an interface, per WebIDL spec 4.1.15. if (RefPtr<MessagePort> port = JSMessagePort::toWrapped(value)) { // Check for duplicate ports. if (portArray.contains(port)) { setDOMException(&state, INVALID_STATE_ERR); return; } portArray.append(WTFMove(port)); } else { if (RefPtr<ArrayBuffer> arrayBuffer = toArrayBuffer(value)) arrayBuffers.append(WTFMove(arrayBuffer)); else { throwTypeError(&state); return; } } } }
static JSC::JSValue dataFunctionMatrix(DataFunctionMatrixToCall f, JSC::ExecState& state, WebGLRenderingContextBase& context) { if (state.argumentCount() != 3) return state.vm().throwException(&state, createNotEnoughArgumentsError(&state)); WebGLUniformLocation* location = JSWebGLUniformLocation::toWrapped(state.uncheckedArgument(0)); if (!location && !state.uncheckedArgument(0).isUndefinedOrNull()) return throwTypeError(&state); bool transpose = state.uncheckedArgument(1).toBoolean(&state); if (state.hadException()) return jsUndefined(); RefPtr<Float32Array> webGLArray = toFloat32Array(state.uncheckedArgument(2)); ExceptionCode ec = 0; if (webGLArray) { switch (f) { case f_uniformMatrix2fv: context.uniformMatrix2fv(location, transpose, *webGLArray, ec); break; case f_uniformMatrix3fv: context.uniformMatrix3fv(location, transpose, *webGLArray, ec); break; case f_uniformMatrix4fv: context.uniformMatrix4fv(location, transpose, *webGLArray, ec); break; } setDOMException(&state, ec); return jsUndefined(); } Vector<float, 64> array; if (!toVector(state, state.uncheckedArgument(2), array)) return throwTypeError(&state); switch (f) { case f_uniformMatrix2fv: context.uniformMatrix2fv(location, transpose, array.data(), array.size(), ec); break; case f_uniformMatrix3fv: context.uniformMatrix3fv(location, transpose, array.data(), array.size(), ec); break; case f_uniformMatrix4fv: context.uniformMatrix4fv(location, transpose, array.data(), array.size(), ec); break; } setDOMException(&state, ec); return jsUndefined(); }
void HTMLPlugInImageElement::didAddUserAgentShadowRoot(ShadowRoot* root) { HTMLPlugInElement::didAddUserAgentShadowRoot(root); if (displayState() >= PreparingPluginReplacement) return; Page* page = document().page(); if (!page) return; // Reset any author styles that may apply as we only want explicit // styles defined in the injected user agents stylesheets to specify // the look-and-feel of the snapshotted plug-in overlay. root->setResetStyleInheritance(true); String mimeType = loadedMimeType(); DOMWrapperWorld& isolatedWorld = plugInImageElementIsolatedWorld(); document().ensurePlugInsInjectedScript(isolatedWorld); ScriptController& scriptController = document().frame()->script(); JSDOMGlobalObject* globalObject = JSC::jsCast<JSDOMGlobalObject*>(scriptController.globalObject(isolatedWorld)); JSC::ExecState* exec = globalObject->globalExec(); JSC::JSLockHolder lock(exec); JSC::MarkedArgumentBuffer argList; argList.append(toJS(exec, globalObject, root)); argList.append(jsString(exec, titleText(page, mimeType))); argList.append(jsString(exec, subtitleText(page, mimeType))); // This parameter determines whether or not the snapshot overlay should always be visible over the plugin snapshot. // If no snapshot was found then we want the overlay to be visible. argList.append(JSC::jsBoolean(!m_snapshotImage)); // It is expected the JS file provides a createOverlay(shadowRoot, title, subtitle) function. JSC::JSObject* overlay = globalObject->get(exec, JSC::Identifier::fromString(exec, "createOverlay")).toObject(exec); if (!overlay) { ASSERT(exec->hadException()); exec->clearException(); return; } JSC::CallData callData; JSC::CallType callType = overlay->methodTable()->getCallData(overlay, callData); if (callType == JSC::CallType::None) return; JSC::call(exec, overlay, callType, callData, globalObject, argList); exec->clearException(); }
bool toVector(JSC::ExecState& state, JSC::JSValue value, Vector<T, inlineCapacity>& vector) { if (!value.isObject()) return false; JSC::JSObject* object = asObject(value); int32_t length = object->get(&state, state.vm().propertyNames->length).toInt32(&state); if (!vector.tryReserveCapacity(length)) return false; vector.resize(length); for (int32_t i = 0; i < length; ++i) { JSC::JSValue v = object->get(&state, i); if (state.hadException()) return false; vector[i] = static_cast<T>(v.toNumber(&state)); } return true; }
void DragData::asFilenames(Vector<String>& result) const { bool success; JSC::JSValue data = m_platformDragData->getData(ClipboardApolloHelper::FILE_LIST_TYPE, success); JSC::ExecState *exec = m_platformDragData->execState(); if (success && data.isObject()) { JSC::JSObject* filenameArray = data.toObject(exec); uint32_t length = filenameArray->get(exec, JSC::Identifier(exec, "length")).toUInt32(exec); for (uint32_t i=0; i<length; i++) { JSC::JSValue fileValue = filenameArray->get(exec, i); if (fileValue.isObject()) { JSC::JSObject* file = fileValue.toObject(exec); JSC::JSValue pathValue = file->get(exec, JSC::Identifier(exec, "nativePath")); if (pathValue.isString()) { String path = ustringToString(pathValue.toString(exec)); result.append(path); } } } } if (exec->hadException()) exec->clearException(); }
RefPtr<WebCore::IDBRequest> IDBObjectStore::putOrAdd(JSC::ExecState& state, JSC::JSValue value, RefPtr<IDBKey> key, IndexedDB::ObjectStoreOverwriteMode overwriteMode, ExceptionCode& ec) { LOG(IndexedDB, "IDBObjectStore::putOrAdd"); if (m_transaction->isReadOnly()) { ec = static_cast<ExceptionCode>(IDBExceptionCode::ReadOnlyError); return nullptr; } if (!m_transaction->isActive()) { ec = static_cast<ExceptionCode>(IDBExceptionCode::TransactionInactiveError); return nullptr; } if (m_deleted) { ec = INVALID_STATE_ERR; return nullptr; } RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(&state, value, nullptr, nullptr); if (state.hadException()) { ec = DATA_CLONE_ERR; return nullptr; } if (serializedValue->hasBlobURLs()) { // FIXME: Add Blob/File/FileList support ec = DATA_CLONE_ERR; return nullptr; } if (key && key->type() == KeyType::Invalid) { ec = static_cast<ExceptionCode>(IDBExceptionCode::DataError); return nullptr; } bool usesInlineKeys = !m_info.keyPath().isNull(); bool usesKeyGenerator = autoIncrement(); if (usesInlineKeys) { if (key) { ec = static_cast<ExceptionCode>(IDBExceptionCode::DataError); return nullptr; } RefPtr<IDBKey> keyPathKey = maybeCreateIDBKeyFromScriptValueAndKeyPath(state, value, m_info.keyPath()); if (keyPathKey && !keyPathKey->isValid()) { ec = static_cast<ExceptionCode>(IDBExceptionCode::DataError); return nullptr; } if (!keyPathKey) { if (usesKeyGenerator) { if (!canInjectIDBKeyIntoScriptValue(state, value, m_info.keyPath())) { ec = static_cast<ExceptionCode>(IDBExceptionCode::DataError); return nullptr; } } else { ec = static_cast<ExceptionCode>(IDBExceptionCode::DataError); return nullptr; } } if (keyPathKey) { ASSERT(!key); key = keyPathKey; } } else if (!usesKeyGenerator && !key) { ec = static_cast<ExceptionCode>(IDBExceptionCode::DataError); return nullptr; } auto context = scriptExecutionContextFromExecState(&state); if (!context) { ec = static_cast<ExceptionCode>(IDBExceptionCode::Unknown); return nullptr; } Ref<IDBRequest> request = m_transaction->requestPutOrAdd(*context, *this, key.get(), *serializedValue, overwriteMode); return adoptRef(request.leakRef()); }
void throwSecurityError(JSC::ExecState& state, const String& message) { ASSERT(!state.hadException()); state.vm().throwException(&state, createDOMException(&state, SECURITY_ERR)); }
static JSC::JSValue dataFunctionf(DataFunctionToCall f, JSC::ExecState& state, WebGLRenderingContextBase& context) { if (state.argumentCount() != 2) return state.vm().throwException(&state, createNotEnoughArgumentsError(&state)); WebGLUniformLocation* location = 0; long index = -1; if (functionForUniform(f)) { location = JSWebGLUniformLocation::toWrapped(state.uncheckedArgument(0)); if (!location && !state.uncheckedArgument(0).isUndefinedOrNull()) return throwTypeError(&state); } else index = state.uncheckedArgument(0).toInt32(&state); if (state.hadException()) return jsUndefined(); RefPtr<Float32Array> webGLArray = toFloat32Array(state.uncheckedArgument(1)); if (state.hadException()) return jsUndefined(); ExceptionCode ec = 0; if (webGLArray) { switch (f) { case f_uniform1v: context.uniform1fv(location, *webGLArray, ec); break; case f_uniform2v: context.uniform2fv(location, *webGLArray, ec); break; case f_uniform3v: context.uniform3fv(location, *webGLArray, ec); break; case f_uniform4v: context.uniform4fv(location, *webGLArray, ec); break; case f_vertexAttrib1v: context.vertexAttrib1fv(index, *webGLArray); break; case f_vertexAttrib2v: context.vertexAttrib2fv(index, *webGLArray); break; case f_vertexAttrib3v: context.vertexAttrib3fv(index, *webGLArray); break; case f_vertexAttrib4v: context.vertexAttrib4fv(index, *webGLArray); break; } setDOMException(&state, ec); return jsUndefined(); } Vector<float, 64> array; if (!toVector(state, state.uncheckedArgument(1), array)) return throwTypeError(&state); switch (f) { case f_uniform1v: context.uniform1fv(location, array.data(), array.size(), ec); break; case f_uniform2v: context.uniform2fv(location, array.data(), array.size(), ec); break; case f_uniform3v: context.uniform3fv(location, array.data(), array.size(), ec); break; case f_uniform4v: context.uniform4fv(location, array.data(), array.size(), ec); break; case f_vertexAttrib1v: context.vertexAttrib1fv(index, array.data(), array.size()); break; case f_vertexAttrib2v: context.vertexAttrib2fv(index, array.data(), array.size()); break; case f_vertexAttrib3v: context.vertexAttrib3fv(index, array.data(), array.size()); break; case f_vertexAttrib4v: context.vertexAttrib4fv(index, array.data(), array.size()); break; } setDOMException(&state, ec); return jsUndefined(); }
RefPtr<IDBRequest> IDBObjectStore::putOrAdd(JSC::ExecState& state, JSC::JSValue value, RefPtr<IDBKey> key, IndexedDB::ObjectStoreOverwriteMode overwriteMode, InlineKeyCheck inlineKeyCheck, ExceptionCodeWithMessage& ec) { LOG(IndexedDB, "IDBObjectStore::putOrAdd"); if (!m_transaction->isActive()) { ec.code = IDBDatabaseException::TransactionInactiveError; ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: The transaction is inactive or finished."); return nullptr; } if (m_transaction->isReadOnly()) { ec.code = IDBDatabaseException::ReadOnlyError; ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: The transaction is read-only."); return nullptr; } if (m_deleted) { ec.code = IDBDatabaseException::InvalidStateError; return nullptr; } RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(&state, value, nullptr, nullptr); if (state.hadException()) { ec.code = IDBDatabaseException::DataCloneError; ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: An object could not be cloned."); return nullptr; } if (serializedValue->hasBlobURLs()) { // FIXME: Add Blob/File/FileList support ec.code = IDBDatabaseException::DataCloneError; ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: BlobURLs are not yet supported."); return nullptr; } if (key && key->type() == KeyType::Invalid) { ec.code = IDBDatabaseException::DataError; return nullptr; } bool usesInlineKeys = !m_info.keyPath().isNull(); bool usesKeyGenerator = autoIncrement(); if (usesInlineKeys && inlineKeyCheck == InlineKeyCheck::Perform) { if (key) { ec.code = IDBDatabaseException::DataError; return nullptr; } RefPtr<IDBKey> keyPathKey = maybeCreateIDBKeyFromScriptValueAndKeyPath(state, value, m_info.keyPath()); if (keyPathKey && !keyPathKey->isValid()) { ec.code = IDBDatabaseException::DataError; return nullptr; } if (!keyPathKey) { if (usesKeyGenerator) { if (!canInjectIDBKeyIntoScriptValue(state, value, m_info.keyPath())) { ec.code = IDBDatabaseException::DataError; return nullptr; } } else { ec.code = IDBDatabaseException::DataError; return nullptr; } } if (keyPathKey) { ASSERT(!key); key = keyPathKey; } } else if (!usesKeyGenerator && !key) { ec.code = IDBDatabaseException::DataError; return nullptr; } auto context = scriptExecutionContextFromExecState(&state); if (!context) { ec.code = IDBDatabaseException::UnknownError; return nullptr; } Ref<IDBRequest> request = m_transaction->requestPutOrAdd(*context, *this, key.get(), *serializedValue, overwriteMode); return adoptRef(request.leakRef()); }