From: Alex Henrie Subject: [PATCH] cmd: Check for correct number of parameters to if command Message-Id: <20210819064842.345266-1-alexhenrie24@gmail.com> Date: Thu, 19 Aug 2021 00:48:42 -0600 WCMD_ReadAndParseLine assumes that if evaluate_if_condition does not return -1 then the command pointer is valid. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51598 Signed-off-by: Alex Henrie --- programs/cmd/builtins.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index c7df724ae00..dfcec83ff5d 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -2792,24 +2792,27 @@ int evaluate_if_condition(WCHAR *p, WCHAR **command, int *test, int *negate) { WCHAR condition[MAX_PATH]; int caseInsensitive = (wcsstr(quals, L"/I") != NULL); + WCHAR *param; *negate = !lstrcmpiW(param1,L"not"); lstrcpyW(condition, (*negate ? param2 : param1)); WINE_TRACE("Condition: %s\n", wine_dbgstr_w(condition)); if (!lstrcmpiW(condition, L"errorlevel")) { - WCHAR *param = WCMD_parameter(p, 1+(*negate), NULL, FALSE, FALSE); WCHAR *endptr; - long int param_int = wcstol(param, &endptr, 10); + long int param_int; + param = WCMD_parameter(p, 1+(*negate), NULL, FALSE, FALSE); + param_int = wcstol(param, &endptr, 10); if (*endptr) goto syntax_err; *test = ((long int)errorlevel >= param_int); - WCMD_parameter(p, 2+(*negate), command, FALSE, FALSE); + param = WCMD_parameter(p, 2+(*negate), command, FALSE, FALSE); } else if (!lstrcmpiW(condition, L"exist")) { WIN32_FIND_DATAW fd; HANDLE hff; - WCHAR *param = WCMD_parameter(p, 1+(*negate), NULL, FALSE, FALSE); - int len = lstrlenW(param); + int len; + param = WCMD_parameter(p, 1+(*negate), NULL, FALSE, FALSE); + len = lstrlenW(param); /* FindFirstFile does not like a directory path ending in '\', append a '.' */ if (len && param[len-1] == '\\') lstrcatW(param, L"."); @@ -2818,35 +2821,34 @@ int evaluate_if_condition(WCHAR *p, WCHAR **command, int *test, int *negate) *test = (hff != INVALID_HANDLE_VALUE ); if (*test) FindClose(hff); - WCMD_parameter(p, 2+(*negate), command, FALSE, FALSE); + param = WCMD_parameter(p, 2+(*negate), command, FALSE, FALSE); } else if (!lstrcmpiW(condition, L"defined")) { - *test = (GetEnvironmentVariableW(WCMD_parameter(p, 1+(*negate), NULL, FALSE, FALSE), - NULL, 0) > 0); - WCMD_parameter(p, 2+(*negate), command, FALSE, FALSE); + param = WCMD_parameter(p, 1+(*negate), NULL, FALSE, FALSE); + *test = (GetEnvironmentVariableW(param, NULL, 0) > 0); + param = WCMD_parameter(p, 2+(*negate), command, FALSE, FALSE); } else { /* comparison operation */ WCHAR leftOperand[MAXSTRING], rightOperand[MAXSTRING], operator[MAXSTRING]; - WCHAR *paramStart; - lstrcpyW(leftOperand, WCMD_parameter(p, (*negate)+caseInsensitive, ¶mStart, TRUE, FALSE)); + lstrcpyW(leftOperand, WCMD_parameter(p, (*negate)+caseInsensitive, ¶m, TRUE, FALSE)); if (!*leftOperand) goto syntax_err; /* Note: '==' can't be returned by WCMD_parameter since '=' is a separator */ - p = paramStart + lstrlenW(leftOperand); + p = param + lstrlenW(leftOperand); while (*p == ' ' || *p == '\t') p++; if (!wcsncmp(p, L"==", lstrlenW(L"=="))) lstrcpyW(operator, L"=="); else { - lstrcpyW(operator, WCMD_parameter(p, 0, ¶mStart, FALSE, FALSE)); + lstrcpyW(operator, WCMD_parameter(p, 0, ¶m, FALSE, FALSE)); if (!*operator) goto syntax_err; } p += lstrlenW(operator); - lstrcpyW(rightOperand, WCMD_parameter(p, 0, ¶mStart, TRUE, FALSE)); + lstrcpyW(rightOperand, WCMD_parameter(p, 0, ¶m, TRUE, FALSE)); if (!*rightOperand) goto syntax_err; @@ -2854,11 +2856,12 @@ int evaluate_if_condition(WCHAR *p, WCHAR **command, int *test, int *negate) if (*test == -1) goto syntax_err; - p = paramStart + lstrlenW(rightOperand); - WCMD_parameter(p, 0, command, FALSE, FALSE); + p = param + lstrlenW(rightOperand); + param = WCMD_parameter(p, 0, command, FALSE, FALSE); } - return 1; + if (*param) + return 1; syntax_err: return -1; -- 2.33.0