Module: wine
Branch: master
Commit: dce5f89e48cc63668b90fbf2a435cbb54bcf4571
URL: https://source.winehq.org/git/wine.git/?a=commit;h=dce5f89e48cc63668b90fbf2…
Author: Jason Edmeades <us(a)edmeades.me.uk>
Date: Sun Jul 15 23:15:28 2018 +0100
cmd: Expand the storage space for qualifiers.
When parsing a command, after the first '/' we store the characters away
in quals. The command itself can be MAXSTRING in bytes, but the quals was
limited to MAX_PATH. This is incorrect, as you can provide very long
qualifiers as well. Expand the space to allow the maximum size possible.
Signed-off-by: Jason Edmeades <us(a)edmeades.me.uk>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
programs/cmd/wcmd.h | 2 +-
programs/cmd/wcmdmain.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h
index d4d97a0..8d6eb6b 100644
--- a/programs/cmd/wcmd.h
+++ b/programs/cmd/wcmd.h
@@ -204,7 +204,7 @@ typedef struct _FOR_CONTEXT {
* (uppercased and concatenated) and parameters entered, with environment
* variables and batch parameters substitution already done.
*/
-extern WCHAR quals[MAX_PATH], param1[MAXSTRING], param2[MAXSTRING];
+extern WCHAR quals[MAXSTRING], param1[MAXSTRING], param2[MAXSTRING];
extern DWORD errorlevel;
extern BATCH_CONTEXT *context;
extern FOR_CONTEXT forloopcontext;
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index 0d02f1f..8fe2d57 100644
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -38,7 +38,7 @@ extern struct env_stack *pushd_directories;
BATCH_CONTEXT *context = NULL;
DWORD errorlevel;
-WCHAR quals[MAX_PATH], param1[MAXSTRING], param2[MAXSTRING];
+WCHAR quals[MAXSTRING], param1[MAXSTRING], param2[MAXSTRING];
BOOL interactive;
FOR_CONTEXT forloopcontext; /* The 'for' loop context */
BOOL delayedsubst = FALSE; /* The current delayed substitution setting */
Module: wine
Branch: master
Commit: 4030a952095398e5a42f0a74213f6a1e9186c4bc
URL: https://source.winehq.org/git/wine.git/?a=commit;h=4030a952095398e5a42f0a74…
Author: Jason Edmeades <us(a)edmeades.me.uk>
Date: Sun Jul 15 23:15:27 2018 +0100
cmd: Handle special case tokens=* in for /f.
for /f allows a special syntax of tokens=* (rather than tokens=1* for example)
which just means put the whole line into the next variable). Note the handling of
the 'next variable' was wrong in the case of it being 'A' or 'a' as the wrap
calculation was wrong, but this only affected using this new syntax.
Signed-off-by: Jason Edmeades <us(a)edmeades.me.uk>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
programs/cmd/builtins.c | 28 ++++++++++++++++++----------
programs/cmd/tests/test_builtins.cmd | 12 ++++++++++++
programs/cmd/tests/test_builtins.cmd.exp | 5 +++++
3 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index ff58484..1ee4fcc 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -1831,6 +1831,14 @@ static int WCMD_for_nexttoken(int lasttoken, WCHAR *tokenstr,
int nextnumber1, nextnumber2 = -1;
WCHAR *nextchar;
+ /* It is valid syntax tokens=* which just means get whole line */
+ if (*pos == '*') {
+ if (doall) *doall = TRUE;
+ if (totalfound) (*totalfound)++;
+ nexttoken = 0;
+ break;
+ }
+
/* Get the next number */
nextnumber1 = strtoulW(pos, &nextchar, 10);
@@ -1959,22 +1967,22 @@ static void WCMD_parse_line(CMD_LIST *cmdStart,
*/
lasttoken = -1;
nexttoken = WCMD_for_nexttoken(lasttoken, forf_tokens, &totalfound,
- NULL, &thisduplicate);
+ &starfound, &thisduplicate);
varidx = FOR_VAR_IDX(variable);
/* Empty out variables */
for (varoffset=0;
- varidx >= 0 && varoffset<totalfound && ((varidx+varoffset)%26);
+ varidx >= 0 && varoffset<totalfound && (((varidx%26) + varoffset) < 26);
varoffset++) {
forloopcontext.variable[varidx + varoffset] = (WCHAR *)nullW;
- /* Stop if we walk beyond z or Z */
- if (((varidx+varoffset) % 26) == 0) break;
}
- /* Loop extracting the tokens */
+ /* Loop extracting the tokens
+ Note: nexttoken of 0 means there were no tokens requested, to handle
+ the special case of tokens=* */
varoffset = 0;
WINE_TRACE("Parsing buffer into tokens: '%s'\n", wine_dbgstr_w(buffer));
- while (varidx >= 0 && (nexttoken > lasttoken)) {
+ while (varidx >= 0 && (nexttoken > 0 && (nexttoken > lasttoken))) {
anyduplicates |= thisduplicate;
/* Extract the token number requested and set into the next variable context */
@@ -1982,9 +1990,9 @@ static void WCMD_parse_line(CMD_LIST *cmdStart,
WINE_TRACE("Parsed token %d(%d) as parameter %s\n", nexttoken,
varidx + varoffset, wine_dbgstr_w(parm));
if (varidx >=0) {
- forloopcontext.variable[varidx + varoffset] = heap_strdupW(parm);
+ if (parm) forloopcontext.variable[varidx + varoffset] = heap_strdupW(parm);
varoffset++;
- if (((varidx + varoffset) %26) == 0) break;
+ if (((varidx%26)+varoffset) >= 26) break;
}
/* Find the next token */
@@ -1995,12 +2003,12 @@ static void WCMD_parse_line(CMD_LIST *cmdStart,
/* If all the rest of the tokens were requested, and there is still space in
the variable range, write them now */
- if (!anyduplicates && starfound && varidx >= 0 && ((varidx+varoffset) % 26)) {
+ if (!anyduplicates && starfound && varidx >= 0 && (((varidx%26) + varoffset) < 26)) {
nexttoken++;
WCMD_parameter_with_delims(buffer, (nexttoken-1), &parm, FALSE, FALSE, forf_delims);
WINE_TRACE("Parsed allremaining tokens (%d) as parameter %s\n",
varidx + varoffset, wine_dbgstr_w(parm));
- forloopcontext.variable[varidx + varoffset] = heap_strdupW(parm);
+ if (parm) forloopcontext.variable[varidx + varoffset] = heap_strdupW(parm);
}
/* Execute the body of the foor loop with these values */
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd
index 0a8122c..5ca2427 100644
--- a/programs/cmd/tests/test_builtins.cmd
+++ b/programs/cmd/tests/test_builtins.cmd
@@ -1744,6 +1744,12 @@ for /f "tokens=1,2,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k
for /f "tokens=1,1,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o
for /f "tokens=2,2,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o
for /f "tokens=3,2,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o
+rem Special case tokens=*
+echo 3.14>testfile
+FOR /F "tokens=*" %%A IN (testfile) DO @echo 1:%%A,%%B
+FOR /F "tokens=1*" %%A IN (testfile) DO @echo 2:%%A,%%B
+FOR /F "tokens=2*" %%A IN (testfile) DO @echo 3:%%A,%%B
+del testfile
cd ..
rd /s/q foobar
echo ------ parameter splitting
@@ -1756,6 +1762,12 @@ goto :forFParameterSplittingEnd
echo %~0 %~1 %~2 %~3 %~4 %~5
goto :eof
:forFParameterSplittingEnd
+echo 3.14>testfile
+FOR /F "delims=. tokens=*" %%A IN (testfile) DO @echo 4:%%A,%%B
+FOR /F "delims=. tokens=1*" %%A IN (testfile) DO @echo 5:%%A,%%B
+FOR /F "delims=. tokens=2*" %%A IN (testfile) DO @echo 6:%%A,%%B
+FOR /F "delims=. tokens=3*" %%A IN (testfile) DO @echo 7:%%A,%%B
+del testfile
echo ------------ Testing del ------------
echo abc > file
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index 7f4f724..0a7c75a 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -1234,9 +1234,14 @@ h=%h i=a j=b k=c l=d e f g m=%m n=%n o=%o@or_broken@h=%h i=a j=b k=c l=d e f g m
h=%h i=a j=c k= l= m=%m n=%n o=%o@or_broken@h=%h i=a j=c k= l= m= n=%n o=%o
h=%h i=b j=c k= l= m=%m n=%n o=%o@or_broken@h=%h i=b j=c k= l= m= n=%n o=%o
h=%h i=b j=c k= l= m=%m n=%n o=%o@or_broken@h=%h i=b j=c k= l= m= n=%n o=%o
+1:3.14,%B
+2:3.14,
------ parameter splitting
:forFParameterSplittingFunc myparam1=myvalue1 myparam2=myparam2 mytest@space@@space@@space@
:forFParameterSplittingFunc myparam1=myvalue1 myparam2=myparam2 mytest@space@@space@@space@
+4:3.14,%B
+5:3,14
+6:14,
------------ Testing del ------------
deleting 'file'
errorlevel is 0, good