diff --git a/dlls/jscript/error.c b/dlls/jscript/error.c index 2aa54368fd5..bced4773351 100644 --- a/dlls/jscript/error.c +++ b/dlls/jscript/error.c @@ -310,6 +310,14 @@ static HRESULT ReferenceErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD fl dispex->ctx->reference_error_constr); } +static HRESULT RegExpErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, + DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + TRACE("\n"); + return error_constr(dispex, flags, dp, retv, ei, + dispex->ctx->regexp_error_constr); +} + static HRESULT SyntaxErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { @@ -341,25 +349,26 @@ HRESULT init_error_constr(script_ctx_t *ctx, DispatchEx *object_prototype) static const WCHAR EvalErrorW[] = {'E','v','a','l','E','r','r','o','r',0}; static const WCHAR RangeErrorW[] = {'R','a','n','g','e','E','r','r','o','r',0}; static const WCHAR ReferenceErrorW[] = {'R','e','f','e','r','e','n','c','e','E','r','r','o','r',0}; + static const WCHAR RegExpErrorW[] = {'R','e','g','E','x','p','E','r','r','o','r',0}; static const WCHAR SyntaxErrorW[] = {'S','y','n','t','a','x','E','r','r','o','r',0}; static const WCHAR TypeErrorW[] = {'T','y','p','e','E','r','r','o','r',0}; static const WCHAR URIErrorW[] = {'U','R','I','E','r','r','o','r',0}; static const WCHAR *names[] = {ErrorW, EvalErrorW, RangeErrorW, - ReferenceErrorW, SyntaxErrorW, TypeErrorW, URIErrorW}; + ReferenceErrorW, RegExpErrorW, SyntaxErrorW, TypeErrorW, URIErrorW}; DispatchEx **constr_addr[] = {&ctx->error_constr, &ctx->eval_error_constr, - &ctx->range_error_constr, &ctx->reference_error_constr, + &ctx->range_error_constr, &ctx->reference_error_constr, &ctx->regexp_error_constr, &ctx->syntax_error_constr, &ctx->type_error_constr, &ctx->uri_error_constr}; static builtin_invoke_t constr_val[] = {ErrorConstr_value, EvalErrorConstr_value, - RangeErrorConstr_value, ReferenceErrorConstr_value, SyntaxErrorConstr_value, - TypeErrorConstr_value, URIErrorConstr_value}; + RangeErrorConstr_value, ReferenceErrorConstr_value, RegExpErrorConstr_value, + SyntaxErrorConstr_value, TypeErrorConstr_value, URIErrorConstr_value}; ErrorInstance *err; INT i; VARIANT v; HRESULT hres; - for(i=0; i<7; i++) { + for(i=0; i < sizeof(names)/sizeof(names[0]); i++) { hres = alloc_error(ctx, i==0 ? object_prototype : NULL, NULL, &err); if(FAILED(hres)) return hres; @@ -433,6 +442,11 @@ HRESULT throw_reference_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const return throw_error(ctx, ei, id, str, ctx->reference_error_constr); } +HRESULT throw_regexp_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str) +{ + return throw_error(ctx, ei, id, str, ctx->regexp_error_constr); +} + HRESULT throw_syntax_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str) { return throw_error(ctx, ei, id, str, ctx->syntax_error_constr); diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index f09e25777a0..6f861b858f3 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -151,6 +151,7 @@ HRESULT Function_value(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IS HRESULT throw_eval_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*); HRESULT throw_range_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*); HRESULT throw_reference_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*); +HRESULT throw_regexp_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*); HRESULT throw_syntax_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*); HRESULT throw_type_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*); HRESULT throw_uri_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*); @@ -208,6 +209,7 @@ struct _script_ctx_t { DispatchEx *eval_error_constr; DispatchEx *range_error_constr; DispatchEx *reference_error_constr; + DispatchEx *regexp_error_constr; DispatchEx *syntax_error_constr; DispatchEx *type_error_constr; DispatchEx *uri_error_constr; diff --git a/dlls/jscript/jscript_En.rc b/dlls/jscript/jscript_En.rc index eca9bc8a8b8..b7f8744d4f8 100644 --- a/dlls/jscript/jscript_En.rc +++ b/dlls/jscript/jscript_En.rc @@ -38,5 +38,6 @@ STRINGTABLE DISCARDABLE IDS_ILLEGAL_ASSIGN "Illegal assignment" IDS_UNDEFINED "'|' is undefined" IDS_NOT_BOOL "Boolean object expected" + IDS_REGEXP_SYNTAX_ERROR "Syntax error in regular expression" IDS_INVALID_LENGTH "Array length must be a finite positive integer" } diff --git a/dlls/jscript/regexp.c b/dlls/jscript/regexp.c index 1c017b01b0f..28154da725b 100644 --- a/dlls/jscript/regexp.c +++ b/dlls/jscript/regexp.c @@ -3819,8 +3819,12 @@ static HRESULT regexp_constructor(script_ctx_t *ctx, DISPPARAMS *dp, VARIANT *re if(FAILED(hres)) return hres; - V_VT(retv) = VT_DISPATCH; - V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(ret); + if(retv) { + V_VT(retv) = VT_DISPATCH; + V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(ret); + }else { + jsdisp_release(ret); + } return S_OK; } @@ -3830,6 +3834,31 @@ static HRESULT RegExpConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DIS TRACE("\n"); switch(flags) { + case DISPATCH_METHOD: + if(arg_cnt(dp)) { + VARIANT *arg = get_arg(dp,0); + if(V_VT(arg) == VT_DISPATCH) { + DispatchEx *jsdisp = iface_to_jsdisp((IUnknown*)V_DISPATCH(arg)); + if(jsdisp) { + if(is_class(jsdisp, JSCLASS_REGEXP)) { + if(arg_cnt(dp) > 1 && V_VT(get_arg(dp,1)) != VT_EMPTY) { + jsdisp_release(jsdisp); + return throw_regexp_error(dispex->ctx, ei, IDS_REGEXP_SYNTAX_ERROR, NULL); + } + + if(retv) { + V_VT(retv) = VT_DISPATCH; + V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(jsdisp); + }else { + jsdisp_release(jsdisp); + } + return S_OK; + } + jsdisp_release(jsdisp); + } + } + } + /* fall through */ case DISPATCH_CONSTRUCT: return regexp_constructor(dispex->ctx, dp, retv); default: diff --git a/dlls/jscript/resource.h b/dlls/jscript/resource.h index 2749bd618c3..9e33ebc9bc0 100644 --- a/dlls/jscript/resource.h +++ b/dlls/jscript/resource.h @@ -34,4 +34,5 @@ #define IDS_ILLEGAL_ASSIGN 0x1390 #define IDS_UNDEFINED 0x1391 #define IDS_NOT_BOOL 0x1392 +#define IDS_REGEXP_SYNTAX_ERROR 0x1399 #define IDS_INVALID_LENGTH 0x13A5 diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index 7a39d0f2d10..7b222124c8e 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -1617,6 +1617,7 @@ exception_test(function() {eval("while(")}, "SyntaxError", -2146827286); exception_test(function() {eval("if(")}, "SyntaxError", -2146827286); exception_test(function() {eval("'unterminated")}, "SyntaxError", -2146827273); exception_test(function() {eval("nonexistingfunc()")}, "TypeError", -2146823281); +exception_test(function() {RegExp(/a/, "g");}, "RegExpError", -2146823271); function testObjectInherit(obj, constr, ts, tls, vo) { ok(obj instanceof Object, "obj is not instance of Object"); diff --git a/dlls/jscript/tests/regexp.js b/dlls/jscript/tests/regexp.js index a839adba9e0..ff98b484072 100644 --- a/dlls/jscript/tests/regexp.js +++ b/dlls/jscript/tests/regexp.js @@ -286,4 +286,16 @@ ok(re.source === "abc[^d]", "re.source = '" + re.source + "', expected 'abc[^d]' re = /a\bc[^d]/g; ok(re.source === "a\\bc[^d]", "re.source = '" + re.source + "', expected 'a\\bc[^d]'"); +re = /abc/; +ok(re === RegExp(re), "re !== RegExp(re)"); + +re = RegExp("abc[^d]", "g"); +ok(re.source === "abc[^d]", "re.source = '" + re.source + "', expected 'abc[^d]'"); + +re = /abc/; +ok(re === RegExp(re, undefined), "re !== RegExp(re, undefined)"); + +re = /abc/; +ok(re === RegExp(re, undefined, 1), "re !== RegExp(re, undefined, 1)"); + reportSuccess();