cmd: Use terminated strings.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48486 Signed-off-by: Gijs Vermeulen <gijsvrm@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
defb7d9c76
commit
0bf71745f0
@ -1533,8 +1533,6 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd,
|
||||
BOOL processThese = executecmds;
|
||||
|
||||
while (*cmdList) {
|
||||
static const WCHAR ifElse[] = {'e','l','s','e'};
|
||||
|
||||
/* execute all appropriate commands */
|
||||
curPosition = *cmdList;
|
||||
|
||||
@ -1566,13 +1564,13 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd,
|
||||
|
||||
/* End of the command - does 'ELSE ' follow as the next command? */
|
||||
} else {
|
||||
if (isIF && WCMD_keyword_ws_found(ifElse, ARRAY_SIZE(ifElse), (*cmdList)->command)) {
|
||||
if (isIF && WCMD_keyword_ws_found(L"else", (*cmdList)->command)) {
|
||||
/* Swap between if and else processing */
|
||||
processThese = !executecmds;
|
||||
|
||||
/* Process the ELSE part */
|
||||
if (processThese) {
|
||||
const int keyw_len = ARRAY_SIZE(ifElse) + 1;
|
||||
const int keyw_len = lstrlenW(L"else") + 1;
|
||||
WCHAR *cmd = ((*cmdList)->command) + keyw_len;
|
||||
|
||||
/* Skip leading whitespace between condition and the command */
|
||||
@ -1599,8 +1597,7 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd,
|
||||
the same bracket depth as the IF, then the IF statement is over. This is required
|
||||
to handle nested ifs properly */
|
||||
} else if (isIF && (*cmdList)->bracketDepth == myDepth) {
|
||||
static const WCHAR doW[] = {'d','o'};
|
||||
if (WCMD_keyword_ws_found(doW, ARRAY_SIZE(doW), (*cmdList)->command)) {
|
||||
if (WCMD_keyword_ws_found(L"do", (*cmdList)->command)) {
|
||||
WINE_TRACE("Still inside FOR-loop, not an end of IF statement\n");
|
||||
*cmdList = (*cmdList)->nextcommand;
|
||||
} else {
|
||||
@ -1642,11 +1639,11 @@ static BOOL WCMD_parse_forf_options(WCHAR *options, WCHAR *eol, int *skip,
|
||||
|
||||
WCHAR *pos = options;
|
||||
int len = lstrlenW(pos);
|
||||
static const WCHAR eolW[] = {'e','o','l','='};
|
||||
static const WCHAR skipW[] = {'s','k','i','p','='};
|
||||
static const WCHAR tokensW[] = {'t','o','k','e','n','s','='};
|
||||
static const WCHAR delimsW[] = {'d','e','l','i','m','s','='};
|
||||
static const WCHAR usebackqW[] = {'u','s','e','b','a','c','k','q'};
|
||||
const int eol_len = lstrlenW(L"eol=");
|
||||
const int skip_len = lstrlenW(L"skip=");
|
||||
const int tokens_len = lstrlenW(L"tokens=");
|
||||
const int delims_len = lstrlenW(L"delims=");
|
||||
const int usebackq_len = lstrlenW(L"usebackq");
|
||||
|
||||
/* Initialize to defaults */
|
||||
lstrcpyW(delims, L" \t");
|
||||
@ -1668,35 +1665,35 @@ static BOOL WCMD_parse_forf_options(WCHAR *options, WCHAR *eol, int *skip,
|
||||
|
||||
/* Save End of line character (Ignore line if first token (based on delims) starts with it) */
|
||||
} else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
|
||||
pos, ARRAY_SIZE(eolW), eolW, ARRAY_SIZE(eolW)) == CSTR_EQUAL) {
|
||||
*eol = *(pos + ARRAY_SIZE(eolW));
|
||||
pos = pos + ARRAY_SIZE(eolW) + 1;
|
||||
pos, eol_len, L"eol=", eol_len) == CSTR_EQUAL) {
|
||||
*eol = *(pos + eol_len);
|
||||
pos = pos + eol_len + 1;
|
||||
WINE_TRACE("Found eol as %c(%x)\n", *eol, *eol);
|
||||
|
||||
/* Save number of lines to skip (Can be in base 10, hex (0x...) or octal (0xx) */
|
||||
} else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
|
||||
pos, ARRAY_SIZE(skipW), skipW, ARRAY_SIZE(skipW)) == CSTR_EQUAL) {
|
||||
pos, skip_len, L"skip=", skip_len) == CSTR_EQUAL) {
|
||||
WCHAR *nextchar = NULL;
|
||||
pos = pos + ARRAY_SIZE(skipW);
|
||||
pos = pos + skip_len;
|
||||
*skip = wcstoul(pos, &nextchar, 0);
|
||||
WINE_TRACE("Found skip as %d lines\n", *skip);
|
||||
pos = nextchar;
|
||||
|
||||
/* Save if usebackq semantics are in effect */
|
||||
} else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, pos,
|
||||
ARRAY_SIZE(usebackqW), usebackqW, ARRAY_SIZE(usebackqW)) == CSTR_EQUAL) {
|
||||
usebackq_len, L"usebackq", usebackq_len) == CSTR_EQUAL) {
|
||||
*usebackq = TRUE;
|
||||
pos = pos + ARRAY_SIZE(usebackqW);
|
||||
pos = pos + usebackq_len;
|
||||
WINE_TRACE("Found usebackq\n");
|
||||
|
||||
/* Save the supplied delims. Slightly odd as space can be a delimiter but only
|
||||
if you finish the optionsroot string with delims= otherwise the space is
|
||||
just a token delimiter! */
|
||||
} else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
|
||||
pos, ARRAY_SIZE(delimsW), delimsW, ARRAY_SIZE(delimsW)) == CSTR_EQUAL) {
|
||||
pos, delims_len, L"delims=", delims_len) == CSTR_EQUAL) {
|
||||
int i=0;
|
||||
|
||||
pos = pos + ARRAY_SIZE(delimsW);
|
||||
pos = pos + delims_len;
|
||||
while (*pos && *pos != ' ') {
|
||||
delims[i++] = *pos;
|
||||
pos++;
|
||||
@ -1707,10 +1704,10 @@ static BOOL WCMD_parse_forf_options(WCHAR *options, WCHAR *eol, int *skip,
|
||||
|
||||
/* Save the tokens being requested */
|
||||
} else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
|
||||
pos, ARRAY_SIZE(tokensW), tokensW, ARRAY_SIZE(tokensW)) == CSTR_EQUAL) {
|
||||
pos, tokens_len, L"tokens=", tokens_len) == CSTR_EQUAL) {
|
||||
int i=0;
|
||||
|
||||
pos = pos + ARRAY_SIZE(tokensW);
|
||||
pos = pos + tokens_len;
|
||||
while (*pos && *pos != ' ') {
|
||||
tokens[i++] = *pos;
|
||||
pos++;
|
||||
@ -2109,8 +2106,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
||||
WIN32_FIND_DATAW fd;
|
||||
HANDLE hff;
|
||||
int i;
|
||||
static const WCHAR inW[] = {'i','n'};
|
||||
static const WCHAR doW[] = {'d','o'};
|
||||
const int in_len = lstrlenW(L"in");
|
||||
CMD_LIST *setStart, *thisSet, *cmdStart, *cmdEnd;
|
||||
WCHAR variable[4];
|
||||
int varidx = -1;
|
||||
@ -2210,7 +2206,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
||||
thisArg = WCMD_parameter(p, parameterNo++, NULL, FALSE, FALSE);
|
||||
if (!thisArg
|
||||
|| !(CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
|
||||
thisArg, ARRAY_SIZE(inW), inW, ARRAY_SIZE(inW)) == CSTR_EQUAL)) {
|
||||
thisArg, in_len, L"in", in_len) == CSTR_EQUAL)) {
|
||||
WCMD_output_stderr (WCMD_LoadMessage(WCMD_SYNTAXERR));
|
||||
return;
|
||||
}
|
||||
@ -2235,7 +2231,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
||||
/* Syntax error if missing close bracket, or nothing following it
|
||||
and once we have the complete set, we expect a DO */
|
||||
WINE_TRACE("Looking for 'do ' in %p\n", *cmdList);
|
||||
if ((*cmdList == NULL) || !WCMD_keyword_ws_found(doW, ARRAY_SIZE(doW), (*cmdList)->command)) {
|
||||
if ((*cmdList == NULL) || !WCMD_keyword_ws_found(L"do", (*cmdList)->command)) {
|
||||
WCMD_output_stderr (WCMD_LoadMessage(WCMD_SYNTAXERR));
|
||||
return;
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **start, BOOL raw, BOOL wholecmdli
|
||||
WCHAR *WCMD_parameter_with_delims (WCHAR *s, int n, WCHAR **start, BOOL raw,
|
||||
BOOL wholecmdline, const WCHAR *delims);
|
||||
WCHAR *WCMD_skip_leading_spaces (WCHAR *string);
|
||||
BOOL WCMD_keyword_ws_found(const WCHAR *keyword, int len, const WCHAR *ptr);
|
||||
BOOL WCMD_keyword_ws_found(const WCHAR *keyword, const WCHAR *ptr);
|
||||
void WCMD_HandleTildeModifiers(WCHAR **start, BOOL atExecute);
|
||||
|
||||
WCHAR *WCMD_strip_quotes(WCHAR *cmd);
|
||||
|
@ -473,7 +473,8 @@ WCHAR *WCMD_skip_leading_spaces (WCHAR *string) {
|
||||
* Checks if the string located at ptr matches a keyword (of length len)
|
||||
* followed by a whitespace character (space or tab)
|
||||
*/
|
||||
BOOL WCMD_keyword_ws_found(const WCHAR *keyword, int len, const WCHAR *ptr) {
|
||||
BOOL WCMD_keyword_ws_found(const WCHAR *keyword, const WCHAR *ptr) {
|
||||
const int len = lstrlenW(keyword);
|
||||
return (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
|
||||
ptr, len, keyword, len) == CSTR_EQUAL)
|
||||
&& ((*(ptr + len) == ' ') || (*(ptr + len) == '\t'));
|
||||
@ -1813,11 +1814,6 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||
CMD_LIST *lastEntry = NULL;
|
||||
CMD_DELIMITERS prevDelim = CMD_NONE;
|
||||
static WCHAR *extraSpace = NULL; /* Deliberately never freed */
|
||||
static const WCHAR remCmd[] = {'r','e','m'};
|
||||
static const WCHAR forCmd[] = {'f','o','r'};
|
||||
static const WCHAR ifCmd[] = {'i','f'};
|
||||
static const WCHAR ifElse[] = {'e','l','s','e'};
|
||||
static const WCHAR setCmd[] = {'s','e','t'};
|
||||
BOOL inOneLine = FALSE;
|
||||
BOOL inFor = FALSE;
|
||||
BOOL inIn = FALSE;
|
||||
@ -1870,10 +1866,7 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||
|
||||
/* Show prompt before batch line IF echo is on and in batch program */
|
||||
if (context && echo_mode && *curPos && (*curPos != '@')) {
|
||||
static const WCHAR echoDot[] = {'e','c','h','o','.'};
|
||||
static const WCHAR echoCol[] = {'e','c','h','o',':'};
|
||||
static const WCHAR echoSlash[] = {'e','c','h','o','/'};
|
||||
const DWORD len = ARRAY_SIZE(echoDot);
|
||||
const DWORD len = lstrlenW(L"echo.");
|
||||
DWORD curr_size = lstrlenW(curPos);
|
||||
DWORD min_len = (curr_size < len ? curr_size : len);
|
||||
WCMD_show_prompt(TRUE);
|
||||
@ -1881,11 +1874,11 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||
/* I don't know why Windows puts a space here but it does */
|
||||
/* Except for lines starting with 'echo.', 'echo:' or 'echo/'. Ask MS why */
|
||||
if (CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
|
||||
curPos, min_len, echoDot, len) != CSTR_EQUAL
|
||||
curPos, min_len, L"echo.", len) != CSTR_EQUAL
|
||||
&& CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
|
||||
curPos, min_len, echoCol, len) != CSTR_EQUAL
|
||||
curPos, min_len, L"echo:", len) != CSTR_EQUAL
|
||||
&& CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
|
||||
curPos, min_len, echoSlash, len) != CSTR_EQUAL)
|
||||
curPos, min_len, L"echo/", len) != CSTR_EQUAL)
|
||||
{
|
||||
WCMD_output_asis(L" ");
|
||||
}
|
||||
@ -1921,13 +1914,11 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||
|
||||
/* Certain commands need special handling */
|
||||
if (curStringLen == 0 && curCopyTo == curString) {
|
||||
static const WCHAR forDO[] = {'d','o'};
|
||||
|
||||
/* If command starts with 'rem ' or identifies a label, ignore any &&, ( etc. */
|
||||
if (WCMD_keyword_ws_found(remCmd, ARRAY_SIZE(remCmd), curPos) || *curPos == ':') {
|
||||
if (WCMD_keyword_ws_found(L"rem", curPos) || *curPos == ':') {
|
||||
inOneLine = TRUE;
|
||||
|
||||
} else if (WCMD_keyword_ws_found(forCmd, ARRAY_SIZE(forCmd), curPos)) {
|
||||
} else if (WCMD_keyword_ws_found(L"for", curPos)) {
|
||||
inFor = TRUE;
|
||||
|
||||
/* If command starts with 'if ' or 'else ', handle ('s mid line. We should ensure this
|
||||
@ -1935,14 +1926,14 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||
should suffice for now.
|
||||
To be able to handle ('s in the condition part take as much as evaluate_if_condition
|
||||
would take and skip parsing it here. */
|
||||
} else if (WCMD_keyword_ws_found(ifCmd, ARRAY_SIZE(ifCmd), curPos)) {
|
||||
} else if (WCMD_keyword_ws_found(L"if", curPos)) {
|
||||
int negate; /* Negate condition */
|
||||
int test; /* Condition evaluation result */
|
||||
WCHAR *p, *command;
|
||||
|
||||
inIf = TRUE;
|
||||
|
||||
p = curPos+(ARRAY_SIZE(ifCmd));
|
||||
p = curPos+(lstrlenW(L"if"));
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
WCMD_parse (p, quals, param1, param2);
|
||||
@ -1960,11 +1951,11 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||
curPos+=if_condition_len;
|
||||
}
|
||||
|
||||
if (WCMD_keyword_ws_found(setCmd, ARRAY_SIZE(setCmd), curPos))
|
||||
if (WCMD_keyword_ws_found(L"set", curPos))
|
||||
ignoreBracket = TRUE;
|
||||
|
||||
} else if (WCMD_keyword_ws_found(ifElse, ARRAY_SIZE(ifElse), curPos)) {
|
||||
const int keyw_len = ARRAY_SIZE(ifElse) + 1;
|
||||
} else if (WCMD_keyword_ws_found(L"else", curPos)) {
|
||||
const int keyw_len = lstrlenW(L"else") + 1;
|
||||
inElse = TRUE;
|
||||
lastWasElse = TRUE;
|
||||
onlyWhiteSpace = TRUE;
|
||||
@ -1985,8 +1976,8 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||
/* In a for loop, the DO command will follow a close bracket followed by
|
||||
whitespace, followed by DO, ie closeBracket inserts a NULL entry, curLen
|
||||
is then 0, and all whitespace is skipped */
|
||||
} else if (inFor && WCMD_keyword_ws_found(forDO, ARRAY_SIZE(forDO), curPos)) {
|
||||
const int keyw_len = ARRAY_SIZE(forDO) + 1;
|
||||
} else if (inFor && WCMD_keyword_ws_found(L"do", curPos)) {
|
||||
const int keyw_len = lstrlenW(L"do") + 1;
|
||||
WINE_TRACE("Found 'DO '\n");
|
||||
lastWasDo = TRUE;
|
||||
onlyWhiteSpace = TRUE;
|
||||
@ -1999,12 +1990,10 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||
|
||||
/* Special handling for the 'FOR' command */
|
||||
if (inFor && lastWasWhiteSpace) {
|
||||
static const WCHAR forIN[] = {'i','n'};
|
||||
|
||||
WINE_TRACE("Found 'FOR ', comparing next parm: '%s'\n", wine_dbgstr_w(curPos));
|
||||
|
||||
if (WCMD_keyword_ws_found(forIN, ARRAY_SIZE(forIN), curPos)) {
|
||||
const int keyw_len = ARRAY_SIZE(forIN) + 1;
|
||||
if (WCMD_keyword_ws_found(L"in", curPos)) {
|
||||
const int keyw_len = lstrlenW(L"in") + 1;
|
||||
WINE_TRACE("Found 'IN '\n");
|
||||
lastWasIn = TRUE;
|
||||
onlyWhiteSpace = TRUE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user