Example #1
0
static HRESULT do_attribute_tag_format(script_ctx_t *ctx, vdisp_t *jsthis, unsigned argc, jsval_t *argv, jsval_t *r,
                                       const WCHAR *tagname, const WCHAR *attrname)
{
    jsstr_t *str, *attr_value = NULL;
    HRESULT hres;

    hres = get_string_val(ctx, jsthis, &str);
    if(FAILED(hres))
        return hres;

    if(argc) {
        hres = to_string(ctx, argv[0], &attr_value);
        if(FAILED(hres)) {
            jsstr_release(str);
            return hres;
        }
    } else {
        attr_value = jsstr_undefined();
    }

    if(r) {
        unsigned attrname_len = strlenW(attrname);
        unsigned tagname_len = strlenW(tagname);
        jsstr_t *ret;
        WCHAR *ptr;

        ptr = jsstr_alloc_buf(2*tagname_len + attrname_len + jsstr_length(attr_value) + jsstr_length(str) + 9, &ret);
        if(ptr) {
            *ptr++ = '<';
            memcpy(ptr, tagname, tagname_len*sizeof(WCHAR));
            ptr += tagname_len;
            *ptr++ = ' ';
            memcpy(ptr, attrname, attrname_len*sizeof(WCHAR));
            ptr += attrname_len;
            *ptr++ = '=';
            *ptr++ = '"';
            ptr += jsstr_flush(attr_value, ptr);
            *ptr++ = '"';
            *ptr++ = '>';
            ptr += jsstr_flush(str, ptr);

            *ptr++ = '<';
            *ptr++ = '/';
            memcpy(ptr, tagname, tagname_len*sizeof(WCHAR));
            ptr += tagname_len;
            *ptr = '>';

            *r = jsval_string(ret);
        } else {
            hres = E_OUTOFMEMORY;
        }
    }

    jsstr_release(attr_value);
    jsstr_release(str);
    return hres;
}
Example #2
0
jsstr_t *jsstr_concat(jsstr_t *str1, jsstr_t *str2)
{
    unsigned len1, len2;
    jsstr_t *ret;
    WCHAR *ptr;

    len1 = jsstr_length(str1);
    if(!len1)
        return jsstr_addref(str2);

    len2 = jsstr_length(str2);
    if(!len2)
        return jsstr_addref(str1);

    if(len1 + len2 >= JSSTR_SHORT_STRING_LENGTH) {
        unsigned depth, depth2;
        jsstr_rope_t *rope;

        depth = jsstr_is_rope(str1) ? jsstr_as_rope(str1)->depth : 0;
        depth2 = jsstr_is_rope(str2) ? jsstr_as_rope(str2)->depth : 0;
        if(depth2 > depth)
            depth = depth2;

        if(depth++ < JSSTR_MAX_ROPE_DEPTH) {
            if(len1+len2 > JSSTR_MAX_LENGTH)
                return NULL;

            rope = heap_alloc(sizeof(*rope));
            if(!rope)
                return NULL;

            jsstr_init(&rope->str, len1+len2, JSSTR_ROPE);
            rope->left = jsstr_addref(str1);
            rope->right = jsstr_addref(str2);
            rope->depth = depth;
            return &rope->str;
        }
    }

    ptr = jsstr_alloc_buf(len1+len2, &ret);
    if(!ret)
        return NULL;

    jsstr_flush(str1, ptr);
    jsstr_flush(str2, ptr+len1);
    return ret;

}
Example #3
0
static HRESULT String_toUpperCase(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
                                  jsval_t *r)
{
    jsstr_t *str;
    HRESULT hres;

    TRACE("\n");

    hres = get_string_val(ctx, jsthis, &str);
    if(FAILED(hres))
        return hres;

    if(r) {
        jsstr_t *ret;
        WCHAR *buf;

        buf = jsstr_alloc_buf(jsstr_length(str), &ret);
        if(!buf) {
            jsstr_release(str);
            return E_OUTOFMEMORY;
        }

        jsstr_flush(str, buf);
        struprW(buf);
        *r = jsval_string(ret);
    }
    jsstr_release(str);
    return S_OK;
}
Example #4
0
const WCHAR *jsstr_rope_flatten(jsstr_rope_t *str)
{
    WCHAR *buf;

    buf = heap_alloc((jsstr_length(&str->str)+1) * sizeof(WCHAR));
    if(!buf)
        return NULL;

    jsstr_flush(str->left, buf);
    jsstr_flush(str->right, buf+jsstr_length(str->left));
    buf[jsstr_length(&str->str)] = 0;

    /* Trasform to heap string */
    jsstr_release(str->left);
    jsstr_release(str->right);
    str->str.length_flags |= JSSTR_FLAG_FLAT;
    return jsstr_as_heap(&str->str)->buf = buf;
}
Example #5
0
static HRESULT strbuf_append_jsstr(strbuf_t *buf, jsstr_t *str)
{
    if(!strbuf_ensure_size(buf, buf->len+jsstr_length(str)))
        return E_OUTOFMEMORY;

    jsstr_flush(str, buf->buf+buf->len);
    buf->len += jsstr_length(str);
    return S_OK;
}
Example #6
0
HRESULT jsval_to_variant(jsval_t val, VARIANT *retv)
{
    switch(jsval_type(val)) {
    case JSV_UNDEFINED:
        V_VT(retv) = VT_EMPTY;
        return S_OK;
    case JSV_NULL:
        V_VT(retv) = VT_NULL;
        return S_OK;
    case JSV_OBJECT:
        V_VT(retv) = VT_DISPATCH;
        if(get_object(val))
            IDispatch_AddRef(get_object(val));
        V_DISPATCH(retv) = get_object(val);
        return S_OK;
    case JSV_STRING: {
        jsstr_t *str = get_string(val);

        V_VT(retv) = VT_BSTR;
        if(str->length_flags & JSSTR_FLAG_NULLBSTR) {
            V_BSTR(retv) = NULL;
        } else {
            V_BSTR(retv) = SysAllocStringLen(NULL, jsstr_length(str));
            if(V_BSTR(retv))
                jsstr_flush(str, V_BSTR(retv));
            else
                return E_OUTOFMEMORY;
        }
        return S_OK;
    }
    case JSV_NUMBER: {
        double n = get_number(val);

        if(is_int32(n)) {
            V_VT(retv) = VT_I4;
            V_I4(retv) = n;
        } else {
            V_VT(retv) = VT_R8;
            V_R8(retv) = n;
        }

        return S_OK;
    }
    case JSV_BOOL:
        V_VT(retv) = VT_BOOL;
        V_BOOL(retv) = get_bool(val) ? VARIANT_TRUE : VARIANT_FALSE;
        return S_OK;
    case JSV_VARIANT:
        V_VT(retv) = VT_EMPTY;
        return VariantCopy(retv, get_variant(val));
    }

    assert(0);
    return E_FAIL;
}
Example #7
0
jsstr_t *jsstr_concat(jsstr_t *str1, jsstr_t *str2)
{
    unsigned len1, len2;
    jsstr_t *ret;

    len1 = jsstr_length(str1);
    if(!len1)
        return jsstr_addref(str2);

    len2 = jsstr_length(str2);
    if(!len2)
        return jsstr_addref(str1);

    ret = jsstr_alloc_buf(len1+len2);
    if(!ret)
        return NULL;

    jsstr_flush(str1, ret->str);
    jsstr_flush(str2, ret->str+len1);
    return ret;
}
Example #8
0
static HRESULT do_attributeless_tag_format(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r, const WCHAR *tagname)
{
    unsigned tagname_len;
    jsstr_t *str, *ret;
    WCHAR *ptr;
    HRESULT hres;

    hres = get_string_val(ctx, jsthis, &str);
    if(FAILED(hres))
        return hres;

    if(!r) {
        jsstr_release(str);
        return S_OK;
    }

    tagname_len = strlenW(tagname);

    ptr = jsstr_alloc_buf(jsstr_length(str) + 2*tagname_len + 5, &ret);
    if(!ret) {
        jsstr_release(str);
        return E_OUTOFMEMORY;
    }

    *ptr++ = '<';
    memcpy(ptr, tagname, tagname_len*sizeof(WCHAR));
    ptr += tagname_len;
    *ptr++ = '>';

    ptr += jsstr_flush(str, ptr);
    jsstr_release(str);

    *ptr++ = '<';
    *ptr++ = '/';
    memcpy(ptr, tagname, tagname_len*sizeof(WCHAR));
    ptr += tagname_len;
    *ptr = '>';

    *r = jsval_string(ret);
    return S_OK;
}
Example #9
0
static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *argv, IDispatch **ret)
{
    WCHAR *str = NULL, *ptr;
    unsigned len = 0, i = 0;
    bytecode_t *code;
    jsdisp_t *function;
    jsstr_t **params = NULL;
    int j = 0;
    HRESULT hres = S_OK;

    static const WCHAR function_anonymousW[] = {'f','u','n','c','t','i','o','n',' ','a','n','o','n','y','m','o','u','s','('};
    static const WCHAR function_beginW[] = {')',' ','{','\n'};
    static const WCHAR function_endW[] = {'\n','}',0};

    if(argc) {
        params = heap_alloc(argc*sizeof(*params));
        if(!params)
            return E_OUTOFMEMORY;

        if(argc > 2)
            len = (argc-2)*2; /* separating commas */
        for(i=0; i < argc; i++) {
            hres = to_string(ctx, argv[i], params+i);
            if(FAILED(hres))
                break;
            len += jsstr_length(params[i]);
        }
    }

    if(SUCCEEDED(hres)) {
        len += (sizeof(function_anonymousW) + sizeof(function_beginW) + sizeof(function_endW)) / sizeof(WCHAR);
        str = heap_alloc(len*sizeof(WCHAR));
        if(str) {
            memcpy(str, function_anonymousW, sizeof(function_anonymousW));
            ptr = str + sizeof(function_anonymousW)/sizeof(WCHAR);
            if(argc > 1) {
                while(1) {
                    ptr += jsstr_flush(params[j], ptr);
                    if(++j == argc-1)
                        break;
                    *ptr++ = ',';
                    *ptr++ = ' ';
                }
            }
            memcpy(ptr, function_beginW, sizeof(function_beginW));
            ptr += sizeof(function_beginW)/sizeof(WCHAR);
            if(argc)
                ptr += jsstr_flush(params[argc-1], ptr);
            memcpy(ptr, function_endW, sizeof(function_endW));

            TRACE("%s\n", debugstr_w(str));
        }else {
            hres = E_OUTOFMEMORY;
        }
    }

    while(i)
        jsstr_release(params[--i]);
    heap_free(params);
    if(FAILED(hres))
        return hres;

    hres = compile_script(ctx, str, NULL, NULL, FALSE, FALSE, &code);
    heap_free(str);
    if(FAILED(hres))
        return hres;

    if(code->global_code.func_cnt != 1 || code->global_code.var_cnt) {
        ERR("Invalid parser result!\n");
        release_bytecode(code);
        return E_UNEXPECTED;
    }

    hres = create_source_function(ctx, code, code->global_code.funcs, NULL, &function);
    release_bytecode(code);
    if(FAILED(hres))
        return hres;

    *ret = to_disp(function);
    return S_OK;
}
Example #10
0
static HRESULT array_join(script_ctx_t *ctx, jsdisp_t *array, DWORD length, const WCHAR *sep, jsval_t *r)
{
    jsstr_t **str_tab, *ret;
    jsval_t val;
    DWORD i;
    HRESULT hres = E_FAIL;

    if(!length) {
        if(r)
            *r = jsval_string(jsstr_empty());
        return S_OK;
    }

    str_tab = heap_alloc_zero(length * sizeof(*str_tab));
    if(!str_tab)
        return E_OUTOFMEMORY;

    for(i=0; i < length; i++) {
        hres = jsdisp_get_idx(array, i, &val);
        if(hres == DISP_E_UNKNOWNNAME) {
            hres = S_OK;
            continue;
        } else if(FAILED(hres))
            break;

        if(!is_undefined(val) && !is_null(val)) {
            hres = to_string(ctx, val, str_tab+i);
            jsval_release(val);
            if(FAILED(hres))
                break;
        }
    }

    if(SUCCEEDED(hres)) {
        DWORD seplen = 0, len = 0;

        seplen = strlenW(sep);

        if(str_tab[0])
            len = jsstr_length(str_tab[0]);
        for(i=1; i < length; i++) {
            len += seplen;
            if(str_tab[i])
                len += jsstr_length(str_tab[i]);
            if(len > JSSTR_MAX_LENGTH) {
                hres = E_OUTOFMEMORY;
                break;
            }
        }

        if(SUCCEEDED(hres)) {
            WCHAR *ptr = NULL;

            ptr = jsstr_alloc_buf(len, &ret);
            if(ptr) {
                if(str_tab[0])
                    ptr += jsstr_flush(str_tab[0], ptr);

                for(i=1; i < length; i++) {
                    if(seplen) {
                        memcpy(ptr, sep, seplen*sizeof(WCHAR));
                        ptr += seplen;
                    }

                    if(str_tab[i])
                        ptr += jsstr_flush(str_tab[i], ptr);
                }
            }else {
                hres = E_OUTOFMEMORY;
            }
        }
    }

    for(i=0; i < length; i++) {
        if(str_tab[i])
            jsstr_release(str_tab[i]);
    }
    heap_free(str_tab);
    if(FAILED(hres))
        return hres;

    TRACE("= %s\n", debugstr_jsstr(ret));

    if(r)
        *r = jsval_string(ret);
    else
        jsstr_release(ret);
    return S_OK;
}
Example #11
0
/* ECMA-262 3rd Edition    15.11.4.4 */
static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
        unsigned argc, jsval_t *argv, jsval_t *r)
{
    jsdisp_t *jsthis;
    jsstr_t *name = NULL, *msg = NULL, *ret = NULL;
    jsval_t v;
    HRESULT hres;

    static const WCHAR object_errorW[] = {'[','o','b','j','e','c','t',' ','E','r','r','o','r',']',0};

    TRACE("\n");

    jsthis = get_jsdisp(vthis);
    if(!jsthis || ctx->version < 2) {
        if(r) {
            jsstr_t *str;

            str = jsstr_alloc(object_errorW);
            if(!str)
                return E_OUTOFMEMORY;
            *r = jsval_string(str);
        }
        return S_OK;
    }

    hres = jsdisp_propget_name(jsthis, nameW, &v);
    if(FAILED(hres))
        return hres;

    if(!is_undefined(v)) {
        hres = to_string(ctx, v, &name);
        jsval_release(v);
        if(FAILED(hres))
            return hres;
    }

    hres = jsdisp_propget_name(jsthis, messageW, &v);
    if(SUCCEEDED(hres)) {
        if(!is_undefined(v)) {
            hres = to_string(ctx, v, &msg);
            jsval_release(v);
        }
    }

    if(SUCCEEDED(hres)) {
        unsigned name_len = name ? jsstr_length(name) : 0;
        unsigned msg_len = msg ? jsstr_length(msg) : 0;

        if(name_len && msg_len) {
            ret = jsstr_alloc_buf(name_len + msg_len + 2);
            if(ret) {
                jsstr_flush(name, ret->str);
                ret->str[name_len] = ':';
                ret->str[name_len+1] = ' ';
                jsstr_flush(msg, ret->str+name_len+2);
            }
        }else if(name_len) {
            ret = name;
            name = NULL;
        }else if(msg_len) {
            ret = msg;
            msg = NULL;
        }else {
            ret = jsstr_alloc(object_errorW);
        }
    }

    if(msg)
        jsstr_release(msg);
    if(name)
        jsstr_release(name);
    if(FAILED(hres))
        return hres;
    if(!ret)
        return E_OUTOFMEMORY;

    if(r)
        *r = jsval_string(ret);
    else
        jsstr_release(ret);
    return S_OK;
}
Example #12
0
HRESULT variant_change_type(script_ctx_t *ctx, VARIANT *dst, VARIANT *src, VARTYPE vt)
{
    jsval_t val;
    HRESULT hres;

    clear_ei(ctx);
    hres = variant_to_jsval(src, &val);
    if(FAILED(hres))
        return hres;

    switch(vt) {
    case VT_I2:
    case VT_I4: {
        INT i;

        hres = to_int32(ctx, val, &i);
        if(SUCCEEDED(hres)) {
            if(vt == VT_I4)
                V_I4(dst) = i;
            else
                V_I2(dst) = i;
        }
        break;
    }
    case VT_R8: {
        double n;
        hres = to_number(ctx, val, &n);
        if(SUCCEEDED(hres))
            V_R8(dst) = n;
        break;
    }
    case VT_R4: {
        double n;

        hres = to_number(ctx, val, &n);
        if(SUCCEEDED(hres))
            V_R4(dst) = n;
        break;
    }
    case VT_BOOL: {
        BOOL b;

        hres = to_boolean(val, &b);
        if(SUCCEEDED(hres))
            V_BOOL(dst) = b ? VARIANT_TRUE : VARIANT_FALSE;
        break;
    }
    case VT_BSTR: {
        jsstr_t *str;

        hres = to_string(ctx, val, &str);
        if(FAILED(hres))
            break;

        if(str->length_flags & JSSTR_FLAG_NULLBSTR) {
            V_BSTR(dst) = NULL;
            break;
        }

        V_BSTR(dst) = SysAllocStringLen(NULL, jsstr_length(str));
        if(V_BSTR(dst))
            jsstr_flush(str, V_BSTR(dst));
        else
            hres = E_OUTOFMEMORY;
        break;
    }
    case VT_EMPTY:
        hres = V_VT(src) == VT_EMPTY ? S_OK : E_NOTIMPL;
        break;
    case VT_NULL:
        hres = V_VT(src) == VT_NULL ? S_OK : E_NOTIMPL;
        break;
    default:
        FIXME("vt %d not implemented\n", vt);
        hres = E_NOTIMPL;
    }

    jsval_release(val);
    if(FAILED(hres))
        return hres;

    V_VT(dst) = vt;
    return S_OK;
}
Example #13
0
/* ECMA-262 3rd Edition    15.5.4.6 */
static HRESULT String_concat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
                             jsval_t *r)
{
    jsstr_t *ret, *str;
    HRESULT hres;

    TRACE("\n");

    hres = get_string_val(ctx, jsthis, &str);
    if(FAILED(hres))
        return hres;

    switch(argc) {
    case 0:
        ret = str;
        break;
    case 1: {
        jsstr_t *arg_str;

        hres = to_string(ctx, argv[0], &arg_str);
        if(FAILED(hres)) {
            jsstr_release(str);
            return hres;
        }

        ret = jsstr_concat(str, arg_str);
        jsstr_release(str);
        if(!ret)
            return E_OUTOFMEMORY;
        break;
    }
    default: {
        const unsigned str_cnt = argc+1;
        unsigned len = 0, i;
        jsstr_t **strs;
        WCHAR *ptr;

        strs = heap_alloc_zero(str_cnt * sizeof(*strs));
        if(!strs) {
            jsstr_release(str);
            return E_OUTOFMEMORY;
        }

        strs[0] = str;
        for(i=0; i < argc; i++) {
            hres = to_string(ctx, argv[i], strs+i+1);
            if(FAILED(hres))
                break;
        }

        if(SUCCEEDED(hres)) {
            for(i=0; i < str_cnt; i++) {
                len += jsstr_length(strs[i]);
                if(len > JSSTR_MAX_LENGTH) {
                    hres = E_OUTOFMEMORY;
                    break;
                }
            }

            if(SUCCEEDED(hres)) {
                ptr = jsstr_alloc_buf(len, &ret);
                if(ptr) {
                    for(i=0; i < str_cnt; i++)
                        ptr += jsstr_flush(strs[i], ptr);
                } else {
                    hres = E_OUTOFMEMORY;
                }
            }
        }

        while(i--)
            jsstr_release(strs[i]);
        heap_free(strs);
        if(FAILED(hres))
            return hres;
    }
    }

    if(r)
        *r = jsval_string(ret);
    else
        jsstr_release(ret);
    return S_OK;
}