From: Yuxuan Shui yshui@codeweavers.com
We didn't check if the argument string is long enough before indexing into it. --- programs/xcopy/xcopy.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/programs/xcopy/xcopy.c b/programs/xcopy/xcopy.c index ce3e40d7d5e..2ea5da00c0d 100644 --- a/programs/xcopy/xcopy.c +++ b/programs/xcopy/xcopy.c @@ -737,9 +737,9 @@ static int XCOPY_ParseCommandLine(WCHAR *suppliedsource, Note: Windows docs say /P prompts when dest is created but tests show it is done for each src file regardless of the destination */ - WCHAR *p = word + 1, *rest; + WCHAR *p = word + 1, *rest, *end = p + wcslen(p);
- while (*p) { + while (p != end) { rest = p + 1;
switch (toupper(*p)) { @@ -763,14 +763,15 @@ static int XCOPY_ParseCommandLine(WCHAR *suppliedsource, OPT_REMOVEARCH; break;
/* E can be /E or /EXCLUDE */ - case 'E': if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, + case 'E': if (p+8<=end && + CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, p, 8, L"EXCLUDE:", -1) == CSTR_EQUAL) { if (XCOPY_ProcessExcludeList(&p[8])) { XCOPY_FailMessage(ERROR_INVALID_PARAMETER); exit(RC_INITERROR); } else { flags |= OPT_EXCLUDELIST; - rest = p + wcslen(p); + rest = end; } } else { flags |= OPT_EMPTYDIR | OPT_RECURSIVE; @@ -778,7 +779,7 @@ static int XCOPY_ParseCommandLine(WCHAR *suppliedsource, break;
/* D can be /D or /D: */ - case 'D': if (p[1]==':' && is_digit(p[2])) { + case 'D': if (p+3<=end && p[1]==':' && is_digit(p[2])) { SYSTEMTIME st; WCHAR *pos = &p[2]; BOOL isError = FALSE; @@ -831,7 +832,7 @@ static int XCOPY_ParseCommandLine(WCHAR *suppliedsource, } break;
- case '-': if (toupper(p[1])=='Y') { + case '-': if (p+2<=end && toupper(p[1])=='Y') { flags &= ~OPT_NOPROMPT; rest = &p[2]; /* Skip over 2 characters */ }