Jacek Caban : jscript: Properly invoke regexp matching in String.split.

Alexandre Julliard julliard at winehq.org
Mon Sep 24 16:04:28 CDT 2012


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Sep 24 15:41:53 2012 +0200

jscript: Properly invoke regexp matching in String.split.

---

 dlls/jscript/string.c        |   42 ++++++++++++++++++------------------------
 dlls/jscript/tests/regexp.js |   22 ++++++++++++++++++++++
 2 files changed, 40 insertions(+), 24 deletions(-)

diff --git a/dlls/jscript/string.c b/dlls/jscript/string.c
index e7216df..6387896 100644
--- a/dlls/jscript/string.c
+++ b/dlls/jscript/string.c
@@ -1081,12 +1081,11 @@ static HRESULT String_small(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
 static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    match_result_t *match_result = NULL;
-    DWORD length, match_cnt, i, match_len = 0;
-    const WCHAR *str, *ptr, *ptr2;
+    match_result_t match_result;
+    DWORD length, i, match_len = 0;
+    const WCHAR *str, *ptr, *ptr2, *cp;
     unsigned limit = UINT32_MAX;
-    BOOL use_regexp = FALSE;
-    jsdisp_t *array;
+    jsdisp_t *array, *regexp = NULL;
     BSTR val_str, match_str = NULL, tmp_str;
     HRESULT hres;
 
@@ -1110,23 +1109,16 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
     }
 
     if(is_object_instance(argv[0])) {
-        jsdisp_t *regexp;
-
         regexp = iface_to_jsdisp((IUnknown*)get_object(argv[0]));
         if(regexp) {
-            if(is_class(regexp, JSCLASS_REGEXP)) {
-                use_regexp = TRUE;
-                hres = regexp_match(ctx, regexp, str, length, TRUE, &match_result, &match_cnt);
-            }
-            jsdisp_release(regexp);
-            if(FAILED(hres)) {
-                SysFreeString(val_str);
-                return hres;
+            if(!is_class(regexp, JSCLASS_REGEXP)) {
+                jsdisp_release(regexp);
+                regexp = NULL;
             }
         }
     }
 
-    if(!use_regexp) {
+    if(!regexp) {
         hres = to_string(ctx, argv[0], &match_str);
         if(FAILED(hres)) {
             SysFreeString(val_str);
@@ -1143,12 +1135,13 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
     hres = create_array(ctx, 0, &array);
 
     if(SUCCEEDED(hres)) {
-        ptr = str;
+        ptr = cp = str;
         for(i=0; i<limit; i++) {
-            if(use_regexp) {
-                if(i == match_cnt)
+            if(regexp) {
+                hres = regexp_match_next(ctx, regexp, 0, str, length, &cp, NULL, NULL, NULL, &match_result);
+                if(hres != S_OK)
                     break;
-                ptr2 = match_result[i].str;
+                ptr2 = match_result.str;
             }else if(match_str) {
                 ptr2 = strstrW(ptr, match_str);
                 if(!ptr2)
@@ -1170,8 +1163,8 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
             if(FAILED(hres))
                 break;
 
-            if(use_regexp)
-                ptr = match_result[i].str + match_result[i].len;
+            if(regexp)
+                ptr = cp;
             else if(match_str)
                 ptr = ptr2 + match_len;
             else
@@ -1179,7 +1172,7 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
         }
     }
 
-    if(SUCCEEDED(hres) && (match_str || use_regexp) && i<limit) {
+    if(SUCCEEDED(hres) && (match_str || regexp) && i<limit) {
         DWORD len = (str+length) - ptr;
 
         if(len || match_str) {
@@ -1194,9 +1187,10 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
         }
     }
 
+    if(regexp)
+        jsdisp_release(regexp);
     SysFreeString(match_str);
     SysFreeString(val_str);
-    heap_free(match_result);
 
     if(SUCCEEDED(hres) && r)
         *r = jsval_obj(array);
diff --git a/dlls/jscript/tests/regexp.js b/dlls/jscript/tests/regexp.js
index 38d5377..6274f93 100644
--- a/dlls/jscript/tests/regexp.js
+++ b/dlls/jscript/tests/regexp.js
@@ -378,6 +378,19 @@ ok(r[2] === "3", "r[2] = " + r[2]);
 ok(RegExp.leftContext === "1,,2", "RegExp.leftContext = " + RegExp.leftContext);
 ok(RegExp.rightContext === "3", "RegExp.rightContext = " + RegExp.rightContext);
 
+r = "1,,2,3".split(/,+/g, 2);
+ok(r.length === 2, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+ok(RegExp.leftContext === "1,,2", "RegExp.leftContext = " + RegExp.leftContext);
+ok(RegExp.rightContext === "3", "RegExp.rightContext = " + RegExp.rightContext);
+
+r = "1,,2,3".split(/,+/g, 1);
+ok(r.length === 1, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(RegExp.leftContext === "1", "RegExp.leftContext = " + RegExp.leftContext);
+ok(RegExp.rightContext === "2,3", "RegExp.rightContext = " + RegExp.rightContext);
+
 r = "1,,2,3".split(/,+/);
 ok(r.length === 3, "r.length = " + r.length);
 ok(r[0] === "1", "r[0] = " + r[0]);
@@ -411,6 +424,15 @@ r = "123".split(re = /\s+/).join(";");
 ok(r === "123", "r = " + r);
 ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
 
+r = "1ab2aab3".split(/(a+)b/);
+ok(r.length === 3, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+ok(r[2] === "3", "r[2] = " + r[2]);
+
+r = "A<B>bold</B>and<CODE>coded</CODE>".split(/<(\/)?([^<>]+)>/) ;
+ok(r.length === 4, "r.length = " + r.length);
+
 /* another standard violation */
 r = "1 12 \t3".split(re = /(\s)+/g).join(";");
 ok(r === "1;12;3", "r = " + r);




More information about the wine-cvs mailing list