void fillMessagePortArray(JSC::ExecState* exec, JSC::JSValue value, MessagePortArray& portArray) { // 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); return; } // Validation of sequence types, per WebIDL spec 4.1.13. unsigned length; JSObject* object = toJSSequence(exec, value, length); if (exec->hadException()) return; portArray.resize(length); for (unsigned i = 0 ; i < length; ++i) { JSValue value = object->get(exec, i); if (exec->hadException()) return; // Validation of non-null objects, per HTML5 spec 8.3.3. if (value.isUndefinedOrNull()) { setDOMException(exec, INVALID_STATE_ERR); return; } // Validation of Objects implementing an interface, per WebIDL spec 4.1.15. RefPtr<MessagePort> port = toMessagePort(value); if (!port) { throwTypeError(exec); return; } portArray[i] = port.release(); } }
void fillMessagePortArray(JSC::ExecState* exec, 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(exec, value, length); if (exec->hadException()) return; for (unsigned i = 0 ; i < length; ++i) { JSValue value = object->get(exec, i); if (exec->hadException()) return; // Validation of non-null objects, per HTML5 spec 10.3.3. if (value.isUndefinedOrNull()) { setDOMException(exec, INVALID_STATE_ERR); return; } // Validation of Objects implementing an interface, per WebIDL spec 4.1.15. RefPtr<MessagePort> port = toMessagePort(value); if (port) { // Check for duplicate ports. if (portArray.contains(port)) { #if MODIFY(ENGINE) //[2014.03.05][infraware][jungong16] : fix to issue. http://www.w3.org/TR/webmessaging/#dom-window-postmessage setDOMException(exec, DATA_CLONE_ERR); #else setDOMException(exec, INVALID_STATE_ERR); #endif return; } portArray.append(port.release()); } else { RefPtr<ArrayBuffer> arrayBuffer = toArrayBuffer(value); if (arrayBuffer) arrayBuffers.append(arrayBuffer); else { throwTypeError(exec); return; } } } }
void JSDictionary::convertValue(ExecState* exec, JSValue value, Vector<String>& result) { if (value.isUndefinedOrNull()) return; unsigned length = 0; JSObject* object = toJSSequence(exec, value, length); if (exec->hadException()) return; for (unsigned i = 0 ; i < length; ++i) { JSValue itemValue = object->get(exec, i); if (exec->hadException()) return; result.append(itemValue.toString(exec)->value(exec)); } }
void fillMessagePortArray(JSC::ExecState* exec, 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(exec, value, length); if (exec->hadException()) return; for (unsigned i = 0 ; i < length; ++i) { JSValue value = object->get(exec, i); if (exec->hadException()) return; // Validation of non-null objects, per HTML5 spec 10.3.3. if (value.isUndefinedOrNull()) { setDOMException(exec, INVALID_STATE_ERR); return; } // Validation of Objects implementing an interface, per WebIDL spec 4.1.15. RefPtr<MessagePort> port = JSMessagePort::toWrapped(value); if (port) { // Check for duplicate ports. if (portArray.contains(port)) { setDOMException(exec, INVALID_STATE_ERR); return; } portArray.append(port.release()); } else { RefPtr<ArrayBuffer> arrayBuffer = toArrayBuffer(value); if (arrayBuffer) arrayBuffers.append(arrayBuffer); else { throwTypeError(exec); return; } } } }
void JSDictionary::convertValue(ExecState* exec, JSValue value, HashSet<AtomicString>& result) { result.clear(); if (value.isUndefinedOrNull()) return; unsigned length; JSObject* object = toJSSequence(exec, value, length); if (exec->hadException()) return; for (unsigned i = 0 ; i < length; ++i) { JSValue itemValue = object->get(exec, i); if (exec->hadException()) return; result.add(ustringToAtomicString(itemValue.toString(exec)->value(exec))); } }
EncodedJSValue JSC_HOST_CALL constructJSFile(ExecState& exec) { auto* constructor = jsCast<DOMConstructorObject*>(exec.callee()); ScriptExecutionContext* context = constructor->scriptExecutionContext(); if (!context) return throwVMError(&exec, createReferenceError(&exec, "File constructor associated document is unavailable")); JSValue arg = exec.argument(0); if (arg.isUndefinedOrNull()) return throwVMTypeError(&exec, ASCIILiteral("First argument to File constructor must be a valid sequence, was undefined or null")); unsigned blobPartsLength = 0; JSObject* blobParts = toJSSequence(exec, arg, blobPartsLength); if (exec.hadException()) return JSValue::encode(jsUndefined()); ASSERT(blobParts); arg = exec.argument(1); if (arg.isUndefined()) return throwVMTypeError(&exec, ASCIILiteral("Second argument to File constructor must be a valid string, was undefined")); String filename = arg.toWTFString(&exec).replace('/', ':'); if (exec.hadException()) return JSValue::encode(jsUndefined()); String normalizedType; Optional<int64_t> lastModified; arg = exec.argument(2); if (!arg.isUndefinedOrNull()) { JSObject* filePropertyBagObject = arg.getObject(); if (!filePropertyBagObject) return throwVMTypeError(&exec, ASCIILiteral("Third argument of the constructor is not of type Object")); // Create the dictionary wrapper from the initializer object. JSDictionary dictionary(&exec, filePropertyBagObject); // Attempt to get the type property. String type; dictionary.get("type", type); if (exec.hadException()) return JSValue::encode(jsUndefined()); normalizedType = Blob::normalizedContentType(type); // Only try to parse the lastModified date if there was not an invalid type argument. if (type.isEmpty() || !normalizedType.isEmpty()) { dictionary.get("lastModified", lastModified); if (exec.hadException()) return JSValue::encode(jsUndefined()); } } if (!lastModified) lastModified = currentTimeMS(); BlobBuilder blobBuilder; for (unsigned i = 0; i < blobPartsLength; ++i) { JSValue item = blobParts->get(&exec, i); if (exec.hadException()) return JSValue::encode(jsUndefined()); if (ArrayBuffer* arrayBuffer = toArrayBuffer(item)) blobBuilder.append(arrayBuffer); else if (RefPtr<ArrayBufferView> arrayBufferView = toArrayBufferView(item)) blobBuilder.append(WTFMove(arrayBufferView)); else if (Blob* blob = JSBlob::toWrapped(item)) blobBuilder.append(blob); else { String string = item.toWTFString(&exec); if (exec.hadException()) return JSValue::encode(jsUndefined()); blobBuilder.append(string, ASCIILiteral("transparent")); } } auto file = File::create(blobBuilder.finalize(), filename, normalizedType, lastModified.value()); return JSValue::encode(CREATE_DOM_WRAPPER(constructor->globalObject(), File, WTFMove(file))); }
EncodedJSValue JSC_HOST_CALL JSBlobConstructor::constructJSBlob(ExecState* exec) { JSBlobConstructor* jsConstructor = jsCast<JSBlobConstructor*>(exec->callee()); ScriptExecutionContext* context = jsConstructor->scriptExecutionContext(); if (!context) return throwVMError(exec, createReferenceError(exec, "Blob constructor associated document is unavailable")); if (!exec->argumentCount()) { RefPtr<Blob> blob = Blob::create(); return JSValue::encode(CREATE_DOM_WRAPPER(jsConstructor->globalObject(), Blob, blob.get())); } unsigned blobPartsLength = 0; JSObject* blobParts = toJSSequence(exec, exec->argument(0), blobPartsLength); if (exec->hadException()) return JSValue::encode(jsUndefined()); ASSERT(blobParts); String type; String endings = ASCIILiteral("transparent"); if (exec->argumentCount() > 1) { JSValue blobPropertyBagValue = exec->argument(1); if (!blobPropertyBagValue.isObject()) return throwVMError(exec, createTypeError(exec, "Second argument of the constructor is not of type Object")); // Given the above test, this will always yield an object. JSObject* blobPropertyBagObject = blobPropertyBagValue.toObject(exec); // Create the dictionary wrapper from the initializer object. JSDictionary dictionary(exec, blobPropertyBagObject); // Attempt to get the endings property and validate it. bool containsEndings = dictionary.get("endings", endings); if (exec->hadException()) return JSValue::encode(jsUndefined()); if (containsEndings) { if (endings != "transparent" && endings != "native") return throwVMError(exec, createTypeError(exec, "The endings property must be either \"transparent\" or \"native\"")); } // Attempt to get the type property. dictionary.get("type", type); if (exec->hadException()) return JSValue::encode(jsUndefined()); } ASSERT(endings == "transparent" || endings == "native"); BlobBuilder blobBuilder; for (unsigned i = 0; i < blobPartsLength; ++i) { JSValue item = blobParts->get(exec, i); if (exec->hadException()) return JSValue::encode(jsUndefined()); #if ENABLE(BLOB) if (ArrayBuffer* arrayBuffer = toArrayBuffer(item)) blobBuilder.append(arrayBuffer); else if (RefPtr<ArrayBufferView> arrayBufferView = toArrayBufferView(item)) blobBuilder.append(arrayBufferView.release()); else #endif if (Blob* blob = toBlob(item)) blobBuilder.append(blob); else { String string = item.toString(exec)->value(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); blobBuilder.append(string, endings); } } RefPtr<Blob> blob = Blob::create(blobBuilder.finalize(), Blob::normalizedContentType(type)); return JSValue::encode(CREATE_DOM_WRAPPER(jsConstructor->globalObject(), Blob, blob.get())); }