[PATCH v5 0/1] MR10404: Draft: vbscript: Reject arguments on Class_Initialize and Class_Terminate.
Windows returns error 1053 when Class_Initialize or Class_Terminate are declared with arguments. Add the same check in compile_class() and store source location in function_decl_t for accurate error reporting. -- v5: vbscript: Reject arguments on Class_Initialize and Class_Terminate. https://gitlab.winehq.org/wine/wine/-/merge_requests/10404
From: Francis De Brabandere <francisdb@gmail.com> Windows returns error 1053 when Class_Initialize or Class_Terminate are declared with arguments. Add the same check in compile_class() and store source location in function_decl_t for accurate error reporting. --- dlls/vbscript/compile.c | 8 ++++++++ dlls/vbscript/parse.h | 1 + dlls/vbscript/parser.y | 19 ++++++++++--------- dlls/vbscript/tests/run.c | 18 ++++++++++++++++++ dlls/vbscript/vbscript.rc | 1 + dlls/vbscript/vbscript_defs.h | 1 + 6 files changed, 39 insertions(+), 9 deletions(-) diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index 345e3b5291b..15b16609ef9 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -1883,6 +1883,10 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl) FIXME("class initializer is not sub\n"); return E_FAIL; } + if(func_decl->args) { + ctx->loc = func_decl->loc; + return MAKE_VBSERROR(VBSE_CLASS_INIT_TERM_NO_ARGS); + } class_desc->class_initialize_id = i; }else if(!wcsicmp(L"class_terminate", func_decl->name)) { @@ -1890,6 +1894,10 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl) FIXME("class terminator is not sub\n"); return E_FAIL; } + if(func_decl->args) { + ctx->loc = func_decl->loc; + return MAKE_VBSERROR(VBSE_CLASS_INIT_TERM_NO_ARGS); + } class_desc->class_terminate_id = i; } diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h index 64c3dee2a69..983057ec904 100644 --- a/dlls/vbscript/parse.h +++ b/dlls/vbscript/parse.h @@ -197,6 +197,7 @@ typedef struct _function_decl_t { BOOL is_default; arg_decl_t *args; statement_t *body; + unsigned loc; struct _function_decl_t *next; struct _function_decl_t *next_prop_func; } function_decl_t; diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index 4977358b333..1ec452ed0a1 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -66,7 +66,7 @@ static dim_decl_t *new_dim_decl(parser_ctx_t*,const WCHAR*,BOOL,dim_list_t*); static dim_list_t *new_dim(parser_ctx_t*,unsigned,dim_list_t*); static redim_decl_t *new_redim_decl(parser_ctx_t*,const WCHAR*,expression_t*); static elseif_decl_t *new_elseif_decl(parser_ctx_t*,unsigned,expression_t*,statement_t*); -static function_decl_t *new_function_decl(parser_ctx_t*,const WCHAR*,function_type_t,unsigned,arg_decl_t*,statement_t*); +static function_decl_t *new_function_decl(parser_ctx_t*,const WCHAR*,function_type_t,unsigned,unsigned,arg_decl_t*,statement_t*); static arg_decl_t *new_argument_decl(parser_ctx_t*,const WCHAR*,BOOL); static const_decl_t *new_const_decl(parser_ctx_t*,const WCHAR*,expression_t*); static case_clausule_t *new_case_clausule(parser_ctx_t*,expression_t*,statement_t*,case_clausule_t*); @@ -492,21 +492,21 @@ ClassBody PropertyDecl : Storage_opt tPROPERTY tGET Identifier ArgumentsDecl_opt StSep BodyStatements tEND tPROPERTY - { $$ = new_function_decl(ctx, $4, FUNC_PROPGET, $1, $5, $7); CHECK_ERROR; } + { $$ = new_function_decl(ctx, $4, FUNC_PROPGET, @2, $1, $5, $7); CHECK_ERROR; } | Storage_opt tPROPERTY tLET Identifier '(' ArgumentDeclList ')' StSep BodyStatements tEND tPROPERTY - { $$ = new_function_decl(ctx, $4, FUNC_PROPLET, $1, $6, $9); CHECK_ERROR; } + { $$ = new_function_decl(ctx, $4, FUNC_PROPLET, @2, $1, $6, $9); CHECK_ERROR; } | Storage_opt tPROPERTY tSET Identifier '(' ArgumentDeclList ')' StSep BodyStatements tEND tPROPERTY - { $$ = new_function_decl(ctx, $4, FUNC_PROPSET, $1, $6, $9); CHECK_ERROR; } + { $$ = new_function_decl(ctx, $4, FUNC_PROPSET, @2, $1, $6, $9); CHECK_ERROR; } FunctionDecl : Storage_opt tSUB Identifier StSep BodyStatements tEND tSUB - { $$ = new_function_decl(ctx, $3, FUNC_SUB, $1, NULL, $5); CHECK_ERROR; } + { $$ = new_function_decl(ctx, $3, FUNC_SUB, @2, $1, NULL, $5); CHECK_ERROR; } | Storage_opt tSUB Identifier ArgumentsDecl Nl_opt BodyStatements tEND tSUB - { $$ = new_function_decl(ctx, $3, FUNC_SUB, $1, $4, $6); CHECK_ERROR; } + { $$ = new_function_decl(ctx, $3, FUNC_SUB, @2, $1, $4, $6); CHECK_ERROR; } | Storage_opt tFUNCTION Identifier StSep BodyStatements tEND tFUNCTION - { $$ = new_function_decl(ctx, $3, FUNC_FUNCTION, $1, NULL, $5); CHECK_ERROR; } + { $$ = new_function_decl(ctx, $3, FUNC_FUNCTION, @2, $1, NULL, $5); CHECK_ERROR; } | Storage_opt tFUNCTION Identifier ArgumentsDecl Nl_opt BodyStatements tEND tFUNCTION - { $$ = new_function_decl(ctx, $3, FUNC_FUNCTION, $1, $4, $6); CHECK_ERROR; } + { $$ = new_function_decl(ctx, $3, FUNC_FUNCTION, @2, $1, $4, $6); CHECK_ERROR; } Storage_opt : /* empty*/ { $$ = 0; } @@ -1073,7 +1073,7 @@ static arg_decl_t *new_argument_decl(parser_ctx_t *ctx, const WCHAR *name, BOOL } static function_decl_t *new_function_decl(parser_ctx_t *ctx, const WCHAR *name, function_type_t type, - unsigned storage_flags, arg_decl_t *arg_decl, statement_t *body) + unsigned loc, unsigned storage_flags, arg_decl_t *arg_decl, statement_t *body) { function_decl_t *decl; BOOL is_default = FALSE; @@ -1098,6 +1098,7 @@ static function_decl_t *new_function_decl(parser_ctx_t *ctx, const WCHAR *name, decl->is_default = is_default; decl->args = arg_decl; decl->body = body; + decl->loc = loc; decl->next = NULL; decl->next_prop_func = NULL; return decl; diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index 1b46cd49393..f2095e1d409 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -2857,6 +2857,24 @@ static void test_parse_errors(void) "end if\n", 2, 1, NULL, E_FAIL + }, + { + /* Class_Initialize with arguments (expected error 1053) */ + L"Class C\n" + "Sub Class_Initialize(x)\n" + "End Sub\n" + "End Class\n", + 1, -23, + NULL, S_OK + }, + { + /* Class_Terminate with arguments (expected error 1053) */ + L"Class C\n" + "Sub Class_Terminate(x)\n" + "End Sub\n" + "End Class\n", + 1, -22, + NULL, S_OK } }; HRESULT hres; diff --git a/dlls/vbscript/vbscript.rc b/dlls/vbscript/vbscript.rc index b9a1c3ad5c3..02f32a88bb5 100644 --- a/dlls/vbscript/vbscript.rc +++ b/dlls/vbscript/vbscript.rc @@ -59,6 +59,7 @@ STRINGTABLE VBSE_INVALID_TYPELIB_VARIABLE "Variable uses an Automation type not supported in VBScript" VBSE_SERVER_NOT_FOUND "The remote server machine does not exist or is unavailable" VBSE_UNQUALIFIED_REFERENCE "Invalid or unqualified reference" + VBSE_CLASS_INIT_TERM_NO_ARGS "Class initialize or terminate do not have arguments" VBS_COMPILE_ERROR "Microsoft VBScript compilation error" VBS_RUNTIME_ERROR "Microsoft VBScript runtime error" diff --git a/dlls/vbscript/vbscript_defs.h b/dlls/vbscript/vbscript_defs.h index e0e9d1cac94..7d57730701c 100644 --- a/dlls/vbscript/vbscript_defs.h +++ b/dlls/vbscript/vbscript_defs.h @@ -270,6 +270,7 @@ #define VBSE_INVALID_TYPELIB_VARIABLE 458 #define VBSE_SERVER_NOT_FOUND 462 #define VBSE_UNQUALIFIED_REFERENCE 505 +#define VBSE_CLASS_INIT_TERM_NO_ARGS 1053 #define VBS_COMPILE_ERROR 4096 #define VBS_RUNTIME_ERROR 4097 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10404
participants (2)
-
Francis De Brabandere -
Francis De Brabandere (@francisdb)