[PATCH v5 0/1] MR10386: vbscript: Add tests for specific compile error codes.
Add error code definitions and string resources for compile errors (1002-1057) and todo_wine tests to verify the error codes returned via OnScriptError. Currently Wine returns error code 0 (generic syntax error) for most cases instead of the specific codes Windows returns. -- v5: vbscript: Add tests for specific compile error codes. https://gitlab.winehq.org/wine/wine/-/merge_requests/10386
From: Francis De Brabandere <francisdb@gmail.com> Add error code definitions and string resources for compile errors (1002-1057) and todo_wine tests to verify the error codes returned via OnScriptError. Currently Wine returns error code 0 (generic syntax error) for most cases instead of the specific codes Windows returns. --- dlls/vbscript/tests/run.c | 164 +++++++++++++++++++++++++++++++--- dlls/vbscript/vbscript.rc | 32 +++++++ dlls/vbscript/vbscript_defs.h | 32 +++++++ 3 files changed, 217 insertions(+), 11 deletions(-) diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index 8aaafbedf54..f6151ba553e 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -1962,6 +1962,7 @@ static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, S static IActiveScriptError **store_script_error; static ULONG error_line; static LONG error_char; +static USHORT error_code; static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror) { @@ -1978,6 +1979,15 @@ static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, I trace("Error in line %lu: %x %s\n", error_line + 1, info.wCode, wine_dbgstr_w(info.bstrDescription)); }else { IDispatchEx *dispex; + EXCEPINFO info; + + hres = IActiveScriptError_GetExceptionInfo(pscripterror, &info); + if(SUCCEEDED(hres)) { + error_code = HRESULT_CODE(info.scode); + SysFreeString(info.bstrSource); + SysFreeString(info.bstrDescription); + SysFreeString(info.bstrHelpFile); + } hres = IActiveScriptError_QueryInterface(pscripterror, &IID_IDispatchEx, (void**)&dispex); ok(hres == E_NOINTERFACE, "QI(IDispatchEx) returned: %08lx\n", hres); @@ -2647,6 +2657,7 @@ static void test_parse_errors(void) const WCHAR *src; unsigned error_line; int error_char; + USHORT error_code; } invalid_scripts[] = { @@ -2654,43 +2665,43 @@ static void test_parse_errors(void) /* If...End If */ L"If 0 > 1 Then\n" " x = 0 End If\n", - 1, 10 + 1, 10, 1042 }, { /* While...End While */ L"While False\n" " x = 0 End While\n", - 1, 10 + 1, 10, 1024 }, { /* While...Wend */ L"While False\n" " x = 0 Wend\n", - 1, 10 + 1, 10, 1025 }, { /* Do While...Loop */ L"Do While False\n" " x = 0 Loop\n", - 1, 10 + 1, 10, 1025 }, { /* Do Until...Loop */ L"Do Until True\n" " x = 0 Loop\n", - 1, 10 + 1, 10, 1025 }, { /* Do...Loop While */ L"Do\n" " x = 0 Loop While False\n", - 1, 10 + 1, 10, 1025 }, { /* Do...Loop Until */ L"Do\n" " x = 0 Loop Until True\n", - 1, 10 + 1, 10, 1025 }, { /* Select...End Select */ @@ -2701,22 +2712,22 @@ static void test_parse_errors(void) " Case 42\n" " x = True End Select\n" "Call ok(x, \"wrong case\")\n", - 5, 17 + 5, 17, 1042 }, { /* Class...End Class (empty) */ L"Class C End Class", - 0, 8 + 0, 8, 1024 }, { /* Class...End Class (empty) */ L"Class C _\nEnd Class", - 1, 0 + 1, 0, 1024 }, { /* invalid use of parentheses for call statement */ L"strcomp(\"x\", \"y\")", - 0, -17 + 0, -17, 1044 }, { L"\n\n\n cint _\n throwInt(&h80001234&)", @@ -2765,6 +2776,133 @@ static void test_parse_errors(void) " throwInt &h87001234&\n" "end if\n", 2, 1 + }, + { + /* Unterminated string constant - error 1033 */ + L"x = \"hello\n", + 0, -10, 1033 + }, + { + /* Expected 'End' - error 1014 */ + L"If True Then\nx = 1\n", + 2, 0, 1014 + }, + { + /* Name redefined - error 1041 */ + L"Dim a\nDim a\n", + 1, -4, 1041 + }, + { + /* Expected identifier - error 1010 */ + L"Dim If\n", + 0, 4, 1010 + }, + { + /* Invalid character - error 1032 */ + L"x = @invalid\n", + 0, 4, 1032 + }, + { + /* Expected literal constant - error 1045 */ + L"Const x = 1 + \"a\"\n", + 0, -17, 1045 + }, + { + /* Expected '(' - error 1005 */ + L"Sub x)\nEnd Sub\n", + 0, 5, 1005 + }, + { + /* Expected '=' - error 1011 */ + L"Const x\n", + 0, 7, 1011 + }, + { + /* Expected 'To' - error 1013 */ + L"For i = 1 x 10\nNext\n", + 0, 10, 1013 + }, + { + /* Expected 'Then' - error 1017 */ + L"If True\nEnd If\n", + 0, 7, 1017 + }, + { + /* Expected 'Wend' - error 1018 */ + L"While True\nx = 1\n", + 2, 0, 1018 + }, + { + /* Expected 'Loop' - error 1019 */ + L"Do\nx = 1\n", + 2, 0, 1019 + }, + { + /* Expected 'Next' - error 1020 */ + L"For i = 1 To 10\nx = 1\n", + 2, 0, 1020 + }, + { + /* Expected 'Case' - error 1021 */ + L"Select x\nEnd Select\n", + 0, 7, 1021 + }, + { + /* Expected integer constant - error 1026 */ + L"Dim x(\"a\")\n", + 0, 6, 1026 + }, + { + /* Invalid number - error 1031 */ + L"x = 1e999\n", + 0, -9, 1031 + }, + { + /* 'loop' without 'do' - error 1038 */ + L"Loop\n", + 0, 0, 1038 + }, + { + /* Invalid 'exit' statement - error 1039 */ + L"Exit Do\n", + 0, -5, 1039 + }, + { + /* Expected 'In' - error 1046 */ + L"For Each x = arr\nNext\n", + 0, 11, 1046 + }, + { + /* Must be defined inside a Class - error 1048 */ + L"Property Get x\nEnd Property\n", + 0, 9, 1048 + }, + { + /* Expected Let or Set or Get - error 1049 */ + L"Class C\nProperty x\nEnd Property\nEnd Class\n", + 1, 9, 1049 + }, + /* TODO: Wine allows arguments on Class_Initialize/Class_Terminate + { + Class initialize/terminate no arguments - error 1053 + L"Class C\nSub Class_Initialize(x)\nEnd Sub\nEnd Class\n", + 1, 20, 1053 + }, + */ + { + /* Property Let/Set needs at least one argument - error 1054 */ + L"Class C\nProperty Let x\nEnd Property\nEnd Class\n", + 1, 14, 1054 + }, + { + /* Unexpected 'Next' - error 1055 */ + L"Next\n", + 0, 0, 1055 + }, + { + /* 'Default' must also specify 'Public' - error 1057 */ + L"Class C\nDefault Private Function f()\nf = 1\nEnd Function\nEnd Class\n", + 1, 0, 1057 } }; HRESULT hres; @@ -2774,6 +2912,7 @@ static void test_parse_errors(void) { error_line = ~0; error_char = -1; + error_code = 0; onerror_hres = S_OK; SET_EXPECT(OnScriptError); @@ -2786,6 +2925,9 @@ static void test_parse_errors(void) todo_wine_if(invalid_scripts[i].error_char < 0) ok(error_char == abs(invalid_scripts[i].error_char), "[%u] error char %ld expected %d\n", i, error_char, invalid_scripts[i].error_char); + if(invalid_scripts[i].error_code) + todo_wine ok(error_code == invalid_scripts[i].error_code, "[%u] error code %u expected %u\n", + i, error_code, invalid_scripts[i].error_code); } } diff --git a/dlls/vbscript/vbscript.rc b/dlls/vbscript/vbscript.rc index cf157f77526..b0641e722e1 100644 --- a/dlls/vbscript/vbscript.rc +++ b/dlls/vbscript/vbscript.rc @@ -57,6 +57,38 @@ 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_SYNTAX_ERROR "Syntax error" + VBSE_EXPECTED_LPAREN "Expected '('" + VBSE_EXPECTED_IDENTIFIER "Expected identifier" + VBSE_EXPECTED_ASSIGN "Expected '='" + VBSE_EXPECTED_TO "Expected 'To'" + VBSE_EXPECTED_END "Expected 'End'" + VBSE_EXPECTED_THEN "Expected 'Then'" + VBSE_EXPECTED_WEND "Expected 'Wend'" + VBSE_EXPECTED_LOOP "Expected 'Loop'" + VBSE_EXPECTED_NEXT "Expected 'Next'" + VBSE_EXPECTED_CASE "Expected 'Case'" + VBSE_EXPECTED_STATEMENT "Expected statement" + VBSE_EXPECTED_END_OF_STATEMENT "Expected end of statement" + VBSE_EXPECTED_INTEGER_CONSTANT "Expected integer constant" + VBSE_EXPECTED_WHILE_UNTIL_EOS "Expected 'While', 'Until' or end of statement" + VBSE_INVALID_NUMBER "Invalid number" + VBSE_INVALID_CHAR "Invalid character" + VBSE_UNTERMINATED_STRING "Unterminated string constant" + VBSE_LOOP_WITHOUT_DO "'loop' without 'do'" + VBSE_INVALID_EXIT "Invalid 'exit' statement" + VBSE_NAME_REDEFINED "Name redefined" + VBSE_MUST_BE_FIRST_STATEMENT "Must be first statement on the line" + VBSE_CANNOT_USE_PARENS_CALLING_SUB "Cannot use parentheses when calling a Sub" + VBSE_EXPECTED_LITERAL_CONSTANT "Expected literal constant" + VBSE_EXPECTED_IN "Expected 'In'" + VBSE_EXPECTED_CLASS "Expected 'Class'" + VBSE_MUST_BE_INSIDE_CLASS "Must be defined inside a Class" + VBSE_EXPECTED_LET_SET_GET "Expected Let or Set or Get in property declaration" + VBSE_CLASS_INIT_NO_ARGS "Class initialize or terminate do not have arguments" + VBSE_PROPERTY_LET_SET_NEEDS_ARG "Property set or let must have at least one argument" + VBSE_UNEXPECTED_NEXT "Unexpected 'Next'" + VBSE_DEFAULT_MUST_BE_PUBLIC "'Default' specification must also specify 'Public'" 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 139b71255a0..3b2ac76ab72 100644 --- a/dlls/vbscript/vbscript_defs.h +++ b/dlls/vbscript/vbscript_defs.h @@ -268,6 +268,38 @@ #define VBSE_INVALID_TYPELIB_VARIABLE 458 #define VBSE_SERVER_NOT_FOUND 462 #define VBSE_UNQUALIFIED_REFERENCE 505 +#define VBSE_SYNTAX_ERROR 1002 +#define VBSE_EXPECTED_LPAREN 1005 +#define VBSE_EXPECTED_IDENTIFIER 1010 +#define VBSE_EXPECTED_ASSIGN 1011 +#define VBSE_EXPECTED_TO 1013 +#define VBSE_EXPECTED_END 1014 +#define VBSE_EXPECTED_THEN 1017 +#define VBSE_EXPECTED_WEND 1018 +#define VBSE_EXPECTED_LOOP 1019 +#define VBSE_EXPECTED_NEXT 1020 +#define VBSE_EXPECTED_CASE 1021 +#define VBSE_EXPECTED_STATEMENT 1024 +#define VBSE_EXPECTED_END_OF_STATEMENT 1025 +#define VBSE_EXPECTED_INTEGER_CONSTANT 1026 +#define VBSE_EXPECTED_WHILE_UNTIL_EOS 1028 +#define VBSE_INVALID_NUMBER 1031 +#define VBSE_INVALID_CHAR 1032 +#define VBSE_UNTERMINATED_STRING 1033 +#define VBSE_LOOP_WITHOUT_DO 1038 +#define VBSE_INVALID_EXIT 1039 +#define VBSE_NAME_REDEFINED 1041 +#define VBSE_MUST_BE_FIRST_STATEMENT 1042 +#define VBSE_CANNOT_USE_PARENS_CALLING_SUB 1044 +#define VBSE_EXPECTED_LITERAL_CONSTANT 1045 +#define VBSE_EXPECTED_IN 1046 +#define VBSE_EXPECTED_CLASS 1047 +#define VBSE_MUST_BE_INSIDE_CLASS 1048 +#define VBSE_EXPECTED_LET_SET_GET 1049 +#define VBSE_CLASS_INIT_NO_ARGS 1053 +#define VBSE_PROPERTY_LET_SET_NEEDS_ARG 1054 +#define VBSE_UNEXPECTED_NEXT 1055 +#define VBSE_DEFAULT_MUST_BE_PUBLIC 1057 #define VBS_COMPILE_ERROR 4096 #define VBS_RUNTIME_ERROR 4097 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10386
@jacek how would you like me to work on this? Merge this first and create MR's for the fixes?
We usually group related commit into a single MR (being careful about how we split commits). Since you already created MRs, we may just as well get this one committed instead. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10386#note_133109
This merge request was approved by Jacek Caban. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10386
participants (3)
-
Francis De Brabandere -
Francis De Brabandere (@francisdb) -
Jacek Caban (@jacek)