Jacek Caban : jscript: Fixed corner cases in parseInt implementation.

Alexandre Julliard julliard at winehq.org
Mon Feb 28 11:02:11 CST 2011


Module: wine
Branch: master
Commit: 04e9b16c5be12233b8a46ea0cb8e1eb81c35fa84
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=04e9b16c5be12233b8a46ea0cb8e1eb81c35fa84

Author: Jacek Caban <jacek at 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);




More information about the wine-cvs mailing list