Module: wine Branch: master Commit: 04e9b16c5be12233b8a46ea0cb8e1eb81c35fa84 URL: http://source.winehq.org/git/wine.git/?a=commit;h=04e9b16c5be12233b8a46ea0cb...
Author: Jacek Caban jacek@codeweavers.com Date: Mon Feb 28 13:11:48 2011 +0100
jscript: Fixed corner cases in parseInt implementation.
---
dlls/jscript/global.c | 45 ++++++++++++++++++++++++++++----------------- dlls/jscript/tests/api.js | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 17 deletions(-)
diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c index ebfc55c..edc8350 100644 --- a/dlls/jscript/global.c +++ b/dlls/jscript/global.c @@ -450,10 +450,10 @@ static INT char_to_int(WCHAR c) static HRESULT JSGlobal_parseInt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { + BOOL neg = FALSE, empty = TRUE; DOUBLE ret = 0.0; - INT radix=10, i; + INT radix=0, i; WCHAR *ptr; - BOOL neg = FALSE; BSTR str; HRESULT hres;
@@ -467,11 +467,11 @@ static HRESULT JSGlobal_parseInt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, if(FAILED(hres)) return hres;
- if(!radix) { - radix = 10; - }else if(radix < 2 || radix > 36) { + if(radix && (radix < 2 || radix > 36)) { WARN("radix %d out of range\n", radix); - return E_FAIL; + if(retv) + num_set_nan(retv); + return S_OK; } }
@@ -489,20 +489,31 @@ static HRESULT JSGlobal_parseInt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, neg = TRUE; ptr++; break; - case '0': - ptr++; - if(*ptr == 'x' || *ptr == 'X') { - radix = 16; - ptr++; - } }
- while(*ptr) { - i = char_to_int(*ptr++); - if(i > radix) - break; + if(!radix) { + if(*ptr == '0') { + if(ptr[1] == 'x' || ptr[1] == 'X') { + radix = 16; + ptr += 2; + }else { + radix = 8; + ptr++; + empty = FALSE; + } + }else { + radix = 10; + } + }
- ret = ret*radix + i; + i = char_to_int(*ptr++); + if(i < radix) { + do { + ret = ret*radix + i; + i = char_to_int(*ptr++); + }while(i < radix); + }else if(empty) { + ret = ret_nan(); }
SysFreeString(str); diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index 482d8b2..45d24b1 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -42,6 +42,48 @@ i = parseInt("123", 10, "test"); ok(i === 123, "parseInt('123', 10, 'test') = " + i); i = parseInt("11", "8"); ok(i === 9, "parseInt('11', '8') = " + i); +i = parseInt("010"); +ok(i === 8, "parseInt('010') = " + i); +i = parseInt(""); +ok(isNaN(i), "parseInt('') = " + i); +i = parseInt("0x"); +ok(isNaN(i), "parseInt('0x') = " + i); +i = parseInt("+"); +ok(isNaN(i), "parseInt('+') = " + i); +i = parseInt("-"); +ok(isNaN(i), "parseInt('-') = " + i); +i = parseInt("0x10", 11); +ok(i === 0, "parseInt('0x10', 11) = " + i); +i = parseInt("010", 7); +ok(i === 7, "parseInt('010', 7) = " + i); +i = parseInt("123abc"); +ok(i === 123, "parseInt('123abc') = " + i); +i = parseInt(" \t123abc"); +ok(i === 123, "parseInt(' \t123abc') = " + i); +i = parseInt("abc"); +ok(isNaN(i), "parseInt('123abc') = " + i); +i = parseInt("-12", 11); +ok(i === -13, "parseInt('-12') = " + i); +i = parseInt("-0x10"); +ok(i === -16, "parseInt('-0x10') = " + i); +i = parseInt("-010"); +ok(i === -8, "parseInt('-010') = " + i); +i = parseInt("123", 0); +ok(i === 123, "parseInt('123', 0) = " + i); +i = parseInt("0x10", 0); +ok(i === 16, "parseInt('123', 0) = " + i); +i = parseInt("0x10", 10); +ok(i === 0, "parseInt('0x10', 10) = " + i); +i = parseInt("0xz"); +ok(isNaN(i), "parseInt('0xz') = " + i); +i = parseInt("1", 1); +ok(isNaN(i), "parseInt('1', 1) = " + i); +i = parseInt("1", -1); +ok(isNaN(i), "parseInt('1', -1) = " + i); +i = parseInt("1", 37); +ok(isNaN(i), "parseInt('1', 37) = " + i); +i = parseInt("1", 36); +ok(i === 1, "parseInt('1', 36) = " + i);
tmp = encodeURI("abc"); ok(tmp === "abc", "encodeURI('abc') = " + tmp);