Module: wine Branch: master Commit: 627e5b3bf1b4236a1eef35eeafb2ef44b7f96dd2 URL: https://gitlab.winehq.org/wine/wine/-/commit/627e5b3bf1b4236a1eef35eeafb2ef4...
Author: Gabriel Ivăncescu gabrielopcode@gmail.com Date: Mon May 29 21:58:37 2023 +0300
jscript: Return undefined for empty RegExp captures in ES5+ mode.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
---
dlls/jscript/jsregexp.c | 23 ++++++++++++++--------- dlls/jscript/tests/regexp.js | 12 ++++++++++++ dlls/mshtml/tests/es5.js | 16 ++++++++++++++++ 3 files changed, 42 insertions(+), 9 deletions(-)
diff --git a/dlls/jscript/jsregexp.c b/dlls/jscript/jsregexp.c index 3775df823c3..af96b63fe70 100644 --- a/dlls/jscript/jsregexp.c +++ b/dlls/jscript/jsregexp.c @@ -361,17 +361,22 @@ static HRESULT create_match_array(script_ctx_t *ctx, jsstr_t *input_str, return hres;
for(i=0; i < result->paren_count; i++) { - if(result->parens[i].index != -1) - str = jsstr_substr(input_str, result->parens[i].index, result->parens[i].length); - else - str = jsstr_empty(); - if(!str) { - hres = E_OUTOFMEMORY; - break; + jsval_t val; + + if(result->parens[i].index != -1) { + if(!(str = jsstr_substr(input_str, result->parens[i].index, result->parens[i].length))) { + hres = E_OUTOFMEMORY; + break; + } + val = jsval_string(str); + }else if(ctx->version < SCRIPTLANGUAGEVERSION_ES5) { + val = jsval_string(jsstr_empty()); + }else { + val = jsval_undefined(); }
- hres = jsdisp_propput_idx(array, i+1, jsval_string(str)); - jsstr_release(str); + hres = jsdisp_propput_idx(array, i+1, val); + jsval_release(val); if(FAILED(hres)) break; } diff --git a/dlls/jscript/tests/regexp.js b/dlls/jscript/tests/regexp.js index 31b83216235..fb6ed0891d5 100644 --- a/dlls/jscript/tests/regexp.js +++ b/dlls/jscript/tests/regexp.js @@ -625,6 +625,18 @@ ok(tmp === "x*y", '"x/y".replace(/[/]/, "*") = ' + tmp); tmp = "x/y".replace(/[xy/]/g, "*"); ok(tmp === "***", '"x/y".replace(/[xy/]/, "*") = ' + tmp);
+tmp = /()/.exec("")[1]; +ok(tmp === "", "/()/ captured: " + tmp); +tmp = /()?/.exec("")[1]; +ok(tmp === "", "/()?/ captured: " + tmp); +tmp = /()??/.exec("")[1]; +ok(tmp === "", "/()??/ captured: " + tmp); +tmp = /()*/.exec("")[1]; +ok(tmp === "", "/()*/ captured: " + tmp); +tmp = /()??()/.exec(""); +ok(tmp[1] === "", "/()??()/ [1] captured: " + tmp); +ok(tmp[2] === "", "/()??()/ [2] captured: " + tmp); + /(b)/.exec("abc"); ok(RegExp.$1 === "b", "RegExp.$1 = " + RegExp.$1); ok("$2" in RegExp, "RegExp.$2 doesn't exist"); diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 982544f6b84..d466c1f9919 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -1610,6 +1610,22 @@ sync_test("isFrozen", function() { } });
+sync_test("RegExp", function() { + var r; + + r = /()/.exec("")[1]; + ok(r === "", "/()/ captured: " + r); + r = /()?/.exec("")[1]; + ok(r === undefined, "/()?/ captured: " + r); + r = /()??/.exec("")[1]; + ok(r === undefined, "/()??/ captured: " + r); + r = /()*/.exec("")[1]; + ok(r === undefined, "/()*/ captured: " + r); + r = /()??()/.exec(""); + ok(r[1] === undefined, "/()??()/ [1] captured: " + r); + ok(r[2] === "", "/()??()/ [2] captured: " + r); +}); + sync_test("builtin_context", function() { var nullDisp = external.nullDisp; var tests = [