static bool cryptoKeyUsagesFromJSValue(ExecState& state, JSValue value, CryptoKeyUsageBitmap& result)
{
    VM& vm = state.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (!isJSArray(value)) {
        throwTypeError(&state, scope);
        return false;
    }

    result = 0;

    JSArray* array = asArray(value);
    for (size_t i = 0; i < array->length(); ++i) {
        JSValue element = array->getIndex(&state, i);
        String usageString = element.toString(&state)->value(&state);
        RETURN_IF_EXCEPTION(scope, false);
        if (usageString == "encrypt")
            result |= CryptoKeyUsageEncrypt;
        else if (usageString == "decrypt")
            result |= CryptoKeyUsageDecrypt;
        else if (usageString == "sign")
            result |= CryptoKeyUsageSign;
        else if (usageString == "verify")
            result |= CryptoKeyUsageVerify;
        else if (usageString == "deriveKey")
            result |= CryptoKeyUsageDeriveKey;
        else if (usageString == "deriveBits")
            result |= CryptoKeyUsageDeriveBits;
        else if (usageString == "wrapKey")
            result |= CryptoKeyUsageWrapKey;
        else if (usageString == "unwrapKey")
            result |= CryptoKeyUsageUnwrapKey;
    }
    return true;
}
ALWAYS_INLINE void SlotVisitor::visitChildren(const JSCell* cell)
{
    ASSERT(Heap::isMarked(cell));

    m_currentObjectCellStateBeforeVisiting = cell->cellState();
    cell->setCellState(CellState::OldBlack);
    
    if (isJSString(cell)) {
        JSString::visitChildren(const_cast<JSCell*>(cell), *this);
        return;
    }

    if (isJSFinalObject(cell)) {
        JSFinalObject::visitChildren(const_cast<JSCell*>(cell), *this);
        return;
    }

    if (isJSArray(cell)) {
        JSArray::visitChildren(const_cast<JSCell*>(cell), *this);
        return;
    }

    cell->methodTable()->visitChildren(const_cast<JSCell*>(cell), *this);
}
Exemple #3
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(exec, jsConstructor->globalObject(), Blob, blob.get()));
    }

    JSValue firstArg = exec->argument(0);
    if (!isJSArray(firstArg))
        return throwVMError(exec, createTypeError(exec, "First argument of the constructor is not of type Array"));

    String type;
    String endings = "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");

    // FIXME: this would be better if the WebKitBlobBuilder were a stack object to avoid the allocation.
    RefPtr<WebKitBlobBuilder> blobBuilder = WebKitBlobBuilder::create();

    JSArray* array = asArray(firstArg);
    unsigned length = array->length();

    for (unsigned i = 0; i < length; ++i) {
        JSValue item = array->getIndex(i);
#if ENABLE(BLOB)
        if (item.inherits(&JSArrayBuffer::s_info))
            blobBuilder->append(toArrayBuffer(item));
        else
#endif
        if (item.inherits(&JSBlob::s_info))
            blobBuilder->append(toBlob(item));
        else {
            String string = ustringToString(item.toString(exec)->value(exec));
            if (exec->hadException())
                return JSValue::encode(jsUndefined());
            blobBuilder->append(string, endings, ASSERT_NO_EXCEPTION);
        }
    }

    RefPtr<Blob> blob = blobBuilder->getBlob(type);
    return JSValue::encode(CREATE_DOM_WRAPPER(exec, jsConstructor->globalObject(), Blob, blob.get()));
}
Exemple #4
0
EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
{
    JSValue thisValue = exec->hostThisValue();
    bool isRealArray = isJSArray(&exec->globalData(), thisValue);
    if (!isRealArray && !thisValue.inherits(&JSArray::info))
        return throwVMTypeError(exec);
    JSArray* thisObj = asArray(thisValue);
    
    HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
    if (arrayVisitedElements.size() >= MaxSmallThreadReentryDepth) {
        if (arrayVisitedElements.size() >= exec->globalData().maxReentryDepth)
            return throwVMError(exec, createStackOverflowError(exec));
    }

    bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
    if (alreadyVisited)
        return JSValue::encode(jsEmptyString(exec)); // return an empty string, avoiding infinite recursion.

//FYWEBKITMOD begin: setting up StringJoiner (while integrating r148721 due to fix of bug 114779). But not using 'ConstructFromLiteral' optimization which we dont have in our webkit.
    unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
    if (exec->hadException())
        return JSValue::encode(jsUndefined());

	//WebCore::String separator(",", WebCore::String::ConstructFromLiteral);
	//JSStringJoiner stringJoiner(separator, length);
	JSStringJoiner stringJoiner(",", length);
//FYWEBKITMOD end
    unsigned totalSize = length ? length - 1 : 0;
    Vector<RefPtr<UString::Rep>, 256> strBuffer(length);
    for (unsigned k = 0; k < length; k++) {
        JSValue element;
        if (isRealArray && thisObj->canGetIndex(k))
            element = thisObj->getIndex(k);
        else {
            element = thisObj->get(exec, k);
//FYWEBKITMOD begin: added while integrating r148721 due to fix of bug 114779
			if (exec->hadException()) 
				return JSValue::encode(jsUndefined());
//FYWEBKITMOD end
			}
        
//FYWEBKITMOD begin: removed (USE_FIX 1) old implementation which joined the strings manually and added usage of JSStringJoiner (while integrating r148721 due to fix of bug 114779)
#define USE_FIX 1 //keep this defined!!!
#ifdef USE_FIX
		if (element.isUndefinedOrNull()) 
			stringJoiner.append(WebCore::String()); //FYWEBKITMOD: 
		else
			stringJoiner.append(element.toString(exec).rep()); //FYWEBKITMOD: using toString() instead of new toWTFString(). Only difference is an optimization used in the toWTFString() case.

		if (exec->hadException())
			return JSValue::encode(jsUndefined());
		}

	arrayVisitedElements.remove(thisObj);

	return JSValue::encode(stringJoiner.build(exec));

#else
        if (element.isUndefinedOrNull())
            continue;
        
        UString str = element.toString(exec);
        strBuffer[k] = str.rep();
        totalSize += str.size();
        
        if (!strBuffer.data()) {
            throwOutOfMemoryError(exec);
        }
        
        if (exec->hadException())
            break;
    }