[PATCH] jscript: Ignore BOM mark in next_token. (try 5)

Qian Hong fracting at gmail.com
Thu Oct 2 06:26:23 CDT 2014


Hi Nikolay,

Thanks for commenting, your thought is helpful as usual :)

I added tests for more space separators, also added tests for parseFloat():
https://testbot.winehq.org/JobDetails.pl?Key=9203&log_206=1#k206

The test result show that, older version of jscript doesn't flow the
standard, while newer version is much better.
The test result also show that, BOM and other space separators are
also ignored in functions like parseFloat.
I'm planing on adding tests for the following group of functions.

parseInt()
eval()
isNaN()
isFinite()
new Number()
new Function()

new Date()
Date.parse()

RegExp()

My idea is fixing the code in lex.c first, then fixing other place
using isspaceW in an incremental way with tests provided, like the
attached patches demos.

Currently there are two troubles bothering me:
1. We need a good way to skip space tests on older IEs
2. We need a good way to reduce the length of WCHAR array for the
jscript code, I believe most of us hate a long array like below...

{'v','a','r',' ','a',' ','=','
','p','a','r','s','e','F','l','o','a','t','(','"',SPACE_HOLDER,'3','.','1','4',SPACE_HOLDER,'"',')',';','o','k','(','a','=','=','3','.','1','4',',','
','"','h','a','h','a','"',')',';','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}

Do you have any advice?

Thanks!
-------------- next part --------------
From f91a71ec42016a8f434a9c46beae1329818da2b5 Mon Sep 17 00:00:00 2001
From: Qian Hong <qhong at codeweavers.com>
Date: Thu, 2 Oct 2014 14:05:50 +0800
Subject: [PATCH 1/2] jscript: Ignore BOM mark in next_token. (try 5)
To: wine-patches <wine-patches at winehq.org>
Reply-To: wine-devel <wine-devel at winehq.org>
Cc: Qian Hong<qhong at codeweavers.com>

---
 dlls/jscript/jscript.h   |  5 ++++
 dlls/jscript/lex.c       |  2 +-
 dlls/jscript/tests/run.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 0273b00..f6af7f4 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -473,6 +473,11 @@ static inline BOOL is_int32(double d)
     return INT32_MIN <= d && d <= INT32_MAX && (double)(int)d == d;
 }
 
+static inline BOOL is_jsspaceW(WCHAR c)
+{
+    return isspaceW(c) || c == 0xFEFF /* UTF16 BOM */;
+}
+
 static inline DWORD make_grfdex(script_ctx_t *ctx, DWORD flags)
 {
     return (ctx->version << 28) | flags;
diff --git a/dlls/jscript/lex.c b/dlls/jscript/lex.c
index b4a3700..fb1bf61 100644
--- a/dlls/jscript/lex.c
+++ b/dlls/jscript/lex.c
@@ -241,7 +241,7 @@ static BOOL skip_comment(parser_ctx_t *ctx)
 
 static BOOL skip_spaces(parser_ctx_t *ctx)
 {
-    while(ctx->ptr < ctx->end && isspaceW(*ctx->ptr)) {
+    while(ctx->ptr < ctx->end && is_jsspaceW(*ctx->ptr)) {
         if(is_endline(*ctx->ptr++))
             ctx->nl = TRUE;
     }
diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c
index aa1783e..abe5521 100644
--- a/dlls/jscript/tests/run.c
+++ b/dlls/jscript/tests/run.c
@@ -144,6 +144,7 @@ DEFINE_EXPECT(DeleteMemberByDispID_false);
 #define DISPID_TESTOBJ_ONLYDISPID   0x2001
 #define DISPID_TESTOBJ_WITHPROP     0x2002
 
+#define JS_E_OUT_OF_MEMORY 0x800a03ec
 #define JS_E_INVALID_CHAR 0x800a03f6
 
 static const WCHAR testW[] = {'t','e','s','t',0};
@@ -1966,6 +1967,70 @@ static void test_script_exprs(void)
     testing_expr = FALSE;
 }
 
+struct spaces_test
+{
+    WCHAR str[1024];
+    HRESULT hres;
+};
+
+#define SPACE_HOLDER 0xBEEF
+static const struct spaces_test spaces_tests[] = {
+    {{'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, S_OK},
+    {{SPACE_HOLDER,'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, S_OK},
+    {{'v',SPACE_HOLDER,'a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, JS_E_OUT_OF_MEMORY},
+    {{'v','a','r',SPACE_HOLDER,' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, S_OK},
+    {{'v','a','r',' ','a',' ','=',' ','1',';',' ',SPACE_HOLDER,'r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, S_OK},
+    {{'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t',SPACE_HOLDER,'S','u','c','c','e','s','s','(',')',';','\0'}, JS_E_OUT_OF_MEMORY},
+    {{'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s',SPACE_HOLDER,'(',')',';','\0'}, S_OK},
+    {{'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',SPACE_HOLDER,')',';','\0'}, S_OK},
+    {{'v','a','r',' ','a',' ','=',SPACE_HOLDER,' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',SPACE_HOLDER,')',';','\0'}, S_OK},
+    {{SPACE_HOLDER,'v','a','r',' ','a',' ','=',SPACE_HOLDER,SPACE_HOLDER,' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',SPACE_HOLDER,')',';','\0'}, S_OK},
+    {{0}}
+};
+
+/* ECMA-252 section 7.2 */
+static const WCHAR spaces[] = {0x0009, 0x000B, 0x000C, 0x0020, 0x00A0, 0xFEFF, 0x1680, 0x2000, 0x2001, 0x2002,
+                               0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x200A, 0x202F, 0x205F, 0x3000, 0};
+
+static void run_space_test(const WCHAR *str, WCHAR space, HRESULT hres)
+{
+        BSTR src = SysAllocString(str);
+        WCHAR *ptr = src;
+        HRESULT res;
+
+        do {
+            if (*ptr == SPACE_HOLDER)
+                *ptr = space;
+        } while (*ptr++);
+
+        if(hres == S_OK)
+        {
+             SET_EXPECT(global_success_d);
+             SET_EXPECT(global_success_i);
+             res = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
+             ok(res == S_OK, "test %s failed with %08x\n", wine_dbgstr_w(src), res);
+             CHECK_CALLED(global_success_d);
+             CHECK_CALLED(global_success_i);
+        }
+        else
+        {
+             res = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
+             todo_wine ok(res == hres, "test %s returned with %08x\n", wine_dbgstr_w(src), res);
+        }
+
+        SysFreeString(src);
+}
+
+static void run_spaces_tests(void)
+{
+    int i, j;
+
+    engine_clsid = &CLSID_JScript;
+    for (i = 0; spaces_tests[i].str[0]; i++)
+        for (j = 0; spaces[j]; j++)
+          run_space_test(spaces_tests[i].str, spaces[j], spaces_tests[i].hres);
+}
+
 static BOOL run_tests(void)
 {
     HRESULT hres;
@@ -2259,6 +2324,8 @@ static BOOL run_tests(void)
         "Object expected",
         NULL);
 
+    run_spaces_tests();
+
     return TRUE;
 }
 
-- 
1.9.1

-------------- next part --------------
From cccb7190844a0a2bd0f76db0184056d92571b32d Mon Sep 17 00:00:00 2001
From: Qian Hong <qhong at codeweavers.com>
Date: Thu, 2 Oct 2014 18:42:52 +0800
Subject: [PATCH 2/2] jscript: Ignore BOM mark in parseFloat.
To: wine-patches <wine-patches at winehq.org>
Reply-To: wine-devel <wine-devel at winehq.org>
Cc: Qian Hong<qhong at codeweavers.com>

---
 dlls/jscript/global.c    | 2 +-
 dlls/jscript/tests/run.c | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c
index 4d1350f..e0300ac 100644
--- a/dlls/jscript/global.c
+++ b/dlls/jscript/global.c
@@ -538,7 +538,7 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
     if(FAILED(hres))
         return hres;
 
-    while(isspaceW(*str)) str++;
+    while(is_jsspaceW(*str)) str++;
 
     if(*str == '+')
         str++;
diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c
index abe5521..422c495 100644
--- a/dlls/jscript/tests/run.c
+++ b/dlls/jscript/tests/run.c
@@ -1985,6 +1985,7 @@ static const struct spaces_test spaces_tests[] = {
     {{'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',SPACE_HOLDER,')',';','\0'}, S_OK},
     {{'v','a','r',' ','a',' ','=',SPACE_HOLDER,' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',SPACE_HOLDER,')',';','\0'}, S_OK},
     {{SPACE_HOLDER,'v','a','r',' ','a',' ','=',SPACE_HOLDER,SPACE_HOLDER,' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',SPACE_HOLDER,')',';','\0'}, S_OK},
+    {{'v','a','r',' ','a',' ','=',' ','p','a','r','s','e','F','l','o','a','t','(','"',SPACE_HOLDER,'3','.','1','4',SPACE_HOLDER,'"',')',';','o','k','(','a','=','=','3','.','1','4',',',' ','"','h','a','h','a','"',')',';','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, S_OK},
     {{0}}
 };
 
-- 
1.9.1



More information about the wine-devel mailing list