Piotr Caban : jscript: Fix parse_double_literal implementation.

Alexandre Julliard julliard at winehq.org
Thu Jun 4 07:59:32 CDT 2009


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

Author: Piotr Caban <piotr.caban at gmail.com>
Date:   Wed Jun  3 23:17:47 2009 +0200

jscript: Fix parse_double_literal implementation.

---

 dlls/jscript/lex.c         |   42 ++++++++++++++++++++++++++++++++++--------
 dlls/jscript/tests/lang.js |    2 ++
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/dlls/jscript/lex.c b/dlls/jscript/lex.c
index c066397..5b7e7a4 100644
--- a/dlls/jscript/lex.c
+++ b/dlls/jscript/lex.c
@@ -31,6 +31,8 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
 
+#define LONGLONG_MAX (((LONGLONG)0x7fffffff<<32)|0xffffffff)
+
 static const WCHAR breakW[] = {'b','r','e','a','k',0};
 static const WCHAR caseW[] = {'c','a','s','e',0};
 static const WCHAR catchW[] = {'c','a','t','c','h',0};
@@ -373,7 +375,8 @@ static literal_t *alloc_int_literal(parser_ctx_t *ctx, LONG l)
 
 static int parse_double_literal(parser_ctx_t *ctx, LONG int_part, literal_t **literal)
 {
-    double d, tmp = 1.0;
+    LONGLONG d, hlp;
+    int exp = 0;
 
     if(ctx->ptr == ctx->end || (!isdigitW(*ctx->ptr) &&
         *ctx->ptr!='.' && *ctx->ptr!='e' && *ctx->ptr!='E')) {
@@ -382,13 +385,32 @@ static int parse_double_literal(parser_ctx_t *ctx, LONG int_part, literal_t **li
     }
 
     d = int_part;
-    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr))
-        d = d*10 + *(ctx->ptr++) - '0';
+    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
+        hlp = d*10 + *(ctx->ptr++) - '0';
+        if(d>LONGLONG_MAX/10 || hlp<0) {
+            exp++;
+            break;
+        }
+        else
+            d = hlp;
+    }
+    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
+        exp++;
+        ctx->ptr++;
+    }
 
     if(*ctx->ptr == '.') ctx->ptr++;
 
+    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
+        hlp = d*10 + *(ctx->ptr++) - '0';
+        if(d>LONGLONG_MAX/10 || hlp<0)
+            break;
+
+        d = hlp;
+        exp--;
+    }
     while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr))
-        d += (tmp /= 10.0)*(*ctx->ptr++ - '0');
+        ctx->ptr++;
 
     if(ctx->ptr < ctx->end && (*ctx->ptr == 'e' || *ctx->ptr == 'E')) {
         int sign = 1, e = 0;
@@ -411,16 +433,20 @@ static int parse_double_literal(parser_ctx_t *ctx, LONG int_part, literal_t **li
             return lex_error(ctx, E_FAIL);
         }
 
-        while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr))
-            e = e*10 + *ctx->ptr++ - '0';
+        while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
+            if(e > INT_MAX/10 || (e = e*10 + *ctx->ptr++ - '0')<0)
+                e = INT_MAX;
+        }
         e *= sign;
 
-        d *= pow(10, e);
+        if(exp<0 && e<0 && e+exp>0) exp = INT_MIN;
+        else if(exp>0 && e>0 && e+exp<0) exp = INT_MAX;
+        else exp += e;
     }
 
     *literal = parser_alloc(ctx, sizeof(literal_t));
     (*literal)->vt = VT_R8;
-    (*literal)->u.dval = d;
+    (*literal)->u.dval = (double)d*pow(10, exp);
 
     return tNumericLiteral;
 }
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js
index c4f0194..86eba86 100644
--- a/dlls/jscript/tests/lang.js
+++ b/dlls/jscript/tests/lang.js
@@ -35,6 +35,8 @@ ok(undefined === undefined, "undefined === undefined is false");
 ok(!(undefined === null), "!(undefined === null) is false");
 ok(1E0 === 1, "1E0 === 1 is false");
 ok(1000000*1000000 === 1000000000000, "1000000*1000000 === 1000000000000 is false");
+ok(8.64e15 === 8640000000000000, "8.64e15 !== 8640000000000000"+8.64e15);
+ok(1e2147483648 === Infinity, "1e2147483648 !== Infinity");
 
 ok(1 !== 2, "1 !== 2 is false");
 ok(null !== undefined, "null !== undefined is false");




More information about the wine-cvs mailing list