Commit d4b670ad authored by Andrew Eikum's avatar Andrew Eikum Committed by Alexandre Julliard

jscript: Implement decodeURIComponent.

parent 6befd9f5
......@@ -930,11 +930,127 @@ static HRESULT JSGlobal_encodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, W
return S_OK;
}
/* ECMA-262 3rd Edition 15.1.3.2 */
static HRESULT JSGlobal_decodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FIXME("\n");
return E_NOTIMPL;
BSTR str, ret;
const WCHAR *ptr;
WCHAR *out_ptr;
DWORD len = 0;
HRESULT hres;
TRACE("\n");
if(!arg_cnt(dp)) {
if(retv) {
ret = SysAllocString(undefinedW);
if(!ret)
return E_OUTOFMEMORY;
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = ret;
}
return S_OK;
}
hres = to_string(ctx, get_arg(dp, 0), ei, &str);
if(FAILED(hres))
return hres;
ptr = str;
while(*ptr) {
if(*ptr == '%') {
char octets[4];
unsigned char mask = 0x80;
int i, size, num_bytes = 0;
if(hex_to_int(*(ptr+1)) < 0 || hex_to_int(*(ptr+2)) < 0) {
FIXME("Throw URIError: Invalid hex sequence\n");
SysFreeString(str);
return E_FAIL;
}
octets[0] = (hex_to_int(*(ptr+1)) << 4) + hex_to_int(*(ptr+2));
ptr += 3;
while(octets[0] & mask) {
mask = mask >> 1;
++num_bytes;
}
if(num_bytes == 1 || num_bytes > 4) {
FIXME("Throw URIError: Invalid initial UTF character\n");
SysFreeString(str);
return E_FAIL;
}
for(i = 1; i < num_bytes; ++i) {
if(*ptr != '%'){
FIXME("Throw URIError: Incomplete UTF sequence\n");
SysFreeString(str);
return E_FAIL;
}
if(hex_to_int(*(ptr+1)) < 0 || hex_to_int(*(ptr+2)) < 0) {
FIXME("Throw URIError: Invalid hex sequence\n");
SysFreeString(str);
return E_FAIL;
}
octets[i] = (hex_to_int(*(ptr+1)) << 4) + hex_to_int(*(ptr+2));
ptr += 3;
}
size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, octets,
num_bytes ? num_bytes : 1, NULL, 0);
if(size == 0) {
FIXME("Throw URIError: Invalid UTF sequence\n");
SysFreeString(str);
return E_FAIL;
}
len += size;
}else {
++ptr;
++len;
}
}
out_ptr = ret = SysAllocStringLen(NULL, len);
if(!ret) {
SysFreeString(str);
return E_OUTOFMEMORY;
}
ptr = str;
while(*ptr) {
if(*ptr == '%') {
char octets[4];
unsigned char mask = 0x80;
int i, size, num_bytes = 0;
octets[0] = (hex_to_int(*(ptr+1)) << 4) + hex_to_int(*(ptr+2));
ptr += 3;
while(octets[0] & mask) {
mask = mask >> 1;
++num_bytes;
}
for(i = 1; i < num_bytes; ++i) {
octets[i] = (hex_to_int(*(ptr+1)) << 4) + hex_to_int(*(ptr+2));
ptr += 3;
}
size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, octets,
num_bytes ? num_bytes : 1, out_ptr, len);
len -= size;
out_ptr += size;
}else {
*out_ptr++ = *ptr++;
--len;
}
}
SysFreeString(str);
if(retv) {
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = ret;
}else {
SysFreeString(ret);
}
return S_OK;
}
static const builtin_prop_t JSGlobal_props[] = {
......
......@@ -60,24 +60,44 @@ ok(tmp === "abc", "encodeURI('abc') = " + tmp);
tmp = encodeURIComponent("abc");
ok(tmp === "abc", "encodeURIComponent('abc') = " + tmp);
dec = decodeURIComponent(tmp);
ok(dec === "abc", "decodeURIComponent('" + tmp + "') = " + dec);
tmp = encodeURIComponent("{abc}");
ok(tmp === "%7Babc%7D", "encodeURIComponent('{abc}') = " + tmp);
dec = decodeURIComponent(tmp);
ok(dec === "{abc}", "decodeURIComponent('" + tmp + "') = " + dec);
tmp = encodeURIComponent("");
ok(tmp === "", "encodeURIComponent('') = " + tmp);
dec = decodeURIComponent(tmp);
ok(dec === "", "decodeURIComponent('" + tmp + "') = " + dec);
tmp = encodeURIComponent("\01\02\03\04");
ok(tmp === "%01%02%03%04", "encodeURIComponent('\\01\\02\\03\\04') = " + tmp);
dec = decodeURIComponent(tmp);
ok(dec === "\01\02\03\04", "decodeURIComponent('" + tmp + "') = " + dec);
tmp = encodeURIComponent("{#@}");
ok(tmp === "%7B%23%40%7D", "encodeURIComponent('{#@}') = " + tmp);
dec = decodeURIComponent(tmp);
ok(dec === "{#@}", "decodeURIComponent('" + tmp + "') = " + dec);
tmp = encodeURIComponent("\xa1 ");
ok(tmp === "%C2%A1%20", "encodeURIComponent(\\xa1 ) = " + tmp);
dec = decodeURIComponent(tmp);
ok(dec === "\xa1 ", "decodeURIComponent('" + tmp + "') = " + dec);
tmp = encodeURIComponent("\xffff");
ok(tmp.length === 8, "encodeURIComponent('\\xffff').length = " + tmp.length);
dec = decodeURIComponent(tmp);
ok(dec === "\xffff", "decodeURIComponent('" + tmp + "') = " + dec);
tmp = encodeURIComponent("abcABC123;/?:@&=+$,-_.!~*'()");
ok(tmp === "abcABC123%3B%2F%3F%3A%40%26%3D%2B%24%2C-_.!~*'()", "encodeURIComponent('abcABC123;/?:@&=+$,-_.!~*'()') = " + tmp);
dec = decodeURIComponent(tmp);
ok(dec === "abcABC123;/?:@&=+$,-_.!~*'()", "decodeURIComponent('" + tmp + "') = " + dec);
tmp = encodeURIComponent();
ok(tmp === "undefined", "encodeURIComponent() = " + tmp);
tmp = encodeURIComponent("abc", "test");
ok(tmp === "abc", "encodeURIComponent('abc') = " + tmp);
dec = decodeURIComponent();
ok(dec === "undefined", "decodeURIComponent() = " + dec);
dec = decodeURIComponent("abc", "test");
ok(dec === "abc", "decodeURIComponent('abc') = " + dec);
tmp = escape("abc");
ok(tmp === "abc", "escape('abc') = " + tmp);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment