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;
            }
        }
    }
}
Exemple #3
0
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)));
}
Exemple #7
0
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()));
}