Author: jmorlan Date: Fri Feb 13 19:13:17 2009 New Revision: 39597
URL: http://svn.reactos.org/svn/reactos?rev=39597&view=rev Log: Make delayed environment-variable expansions actually be delayed.
Modified: trunk/reactos/base/shell/cmd/cmd.c trunk/reactos/base/shell/cmd/cmd.h trunk/reactos/base/shell/cmd/if.c trunk/reactos/base/shell/cmd/redir.c
Modified: trunk/reactos/base/shell/cmd/cmd.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/cmd.c?rev=39... ============================================================================== --- trunk/reactos/base/shell/cmd/cmd.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/cmd.c [iso-8859-1] Fri Feb 13 19:13:17 2009 @@ -868,6 +868,7 @@ { BOOL bNewBatch = TRUE; PARSED_COMMAND *Sub; + LPTSTR ExpandedLine; BOOL Success = TRUE;
if (!PerformRedirection(Cmd->Redirections)) @@ -879,7 +880,14 @@ if(bc) bNewBatch = FALSE;
- Success = DoCommand(Cmd->Command.CommandLine); + ExpandedLine = DoDelayedExpansion(Cmd->Command.CommandLine); + if (!ExpandedLine) + { + Success = FALSE; + break; + } + Success = DoCommand(ExpandedLine); + cmd_free(ExpandedLine);
if(bNewBatch && bc) AddBatchRedirection(&Cmd->Redirections); @@ -1097,8 +1105,11 @@ return NULL; }
+BOOL bNoInteractive; +BOOL bIsBatch; + BOOL -SubstituteVars(TCHAR *Src, TCHAR *Dest, TCHAR Delim, BOOL bIsBatch) +SubstituteVars(TCHAR *Src, TCHAR *Dest, TCHAR Delim) { #define APPEND(From, Length) { \ if (Dest + (Length) > DestEnd) \ @@ -1250,14 +1261,26 @@ #undef APPEND1 }
+LPTSTR +DoDelayedExpansion(LPTSTR Line) +{ + TCHAR Buf[CMDLINE_LENGTH]; + if (!_tcschr(Line, _T('!'))) + return cmd_dup(Line); + + /* FIXME: Delayed substitutions actually aren't quite the same as + * immediate substitutions. In particular, it's possible to escape + * the exclamation point using ^. */ + if (!SubstituteVars(Line, Buf, _T('!'))) + return NULL; + return cmd_dup(Buf); +} +
/* * do the prompt/input/process loop * */ - -BOOL bNoInteractive; -BOOL bIsBatch;
BOOL ReadLine (TCHAR *commandline, BOOL bMore) @@ -1299,15 +1322,7 @@ bIsBatch = TRUE; }
- if (!SubstituteVars(ip, commandline, _T('%'), bIsBatch)) - return FALSE; - - /* FIXME: !vars! should be substituted later, after parsing. */ - if (!SubstituteVars(commandline, readline, _T('!'), bIsBatch)) - return FALSE; - _tcscpy(commandline, readline); - - return TRUE; + return SubstituteVars(ip, commandline, _T('%')); }
static INT
Modified: trunk/reactos/base/shell/cmd/cmd.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/cmd.h?rev=39... ============================================================================== --- trunk/reactos/base/shell/cmd/cmd.h [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/cmd.h [iso-8859-1] Fri Feb 13 19:13:17 2009 @@ -102,6 +102,7 @@ LPCTSTR GetEnvVarOrSpecial ( LPCTSTR varName ); VOID AddBreakHandler (VOID); VOID RemoveBreakHandler (VOID); +LPTSTR DoDelayedExpansion(LPTSTR Line); BOOL DoCommand (LPTSTR line); BOOL ReadLine(TCHAR *commandline, BOOL bMore); int cmd_main (int argc, const TCHAR *argv[]);
Modified: trunk/reactos/base/shell/cmd/if.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/if.c?rev=395... ============================================================================== --- trunk/reactos/base/shell/cmd/if.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/if.c [iso-8859-1] Fri Feb 13 19:13:17 2009 @@ -67,15 +67,30 @@ { INT result = FALSE; /* when set cause 'then' clause to be executed */ LPTSTR param; + LPTSTR Left = NULL, Right; + + if (Cmd->If.LeftArg) + { + Left = DoDelayedExpansion(Cmd->If.LeftArg); + if (!Left) + return FALSE; + } + Right = DoDelayedExpansion(Cmd->If.RightArg); + if (!Right) + { + cmd_free(Left); + return FALSE; + }
if (Cmd->If.Operator == IF_CMDEXTVERSION) { /* IF CMDEXTVERSION n: check if Command Extensions version * is greater or equal to n */ - DWORD n = _tcstoul(Cmd->If.RightArg, ¶m, 10); + DWORD n = _tcstoul(Right, ¶m, 10); if (*param != _T('\0')) { - error_syntax(Cmd->If.RightArg); + error_syntax(Right); + cmd_free(Right); return FALSE; } result = (2 >= n); @@ -83,7 +98,7 @@ else if (Cmd->If.Operator == IF_DEFINED) { /* IF DEFINED var: check if environment variable exists */ - result = (GetEnvVarOrSpecial(Cmd->If.RightArg) != NULL); + result = (GetEnvVarOrSpecial(Right) != NULL); } else if (Cmd->If.Operator == IF_ERRORLEVEL) { @@ -91,7 +106,8 @@ INT n = _tcstol(Cmd->If.RightArg, ¶m, 10); if (*param != _T('\0')) { - error_syntax(Cmd->If.RightArg); + error_syntax(Right); + cmd_free(Right); return FALSE; } result = (nErrorLevel >= n); @@ -102,9 +118,9 @@ WIN32_FIND_DATA f; HANDLE hFind;
- StripQuotes(Cmd->If.RightArg); + StripQuotes(Right);
- hFind = FindFirstFile(Cmd->If.RightArg, &f); + hFind = FindFirstFile(Right, &f); if (hFind != INVALID_HANDLE_VALUE) { result = TRUE; @@ -120,11 +136,11 @@ if (Cmd->If.Operator == IF_STRINGEQ) { /* IF str1 == str2 */ - result = StringCmp(Cmd->If.LeftArg, Cmd->If.RightArg) == 0; + result = StringCmp(Left, Right) == 0; } else { - result = GenericCmp(StringCmp, Cmd->If.LeftArg, Cmd->If.RightArg); + result = GenericCmp(StringCmp, Left, Right); switch (Cmd->If.Operator) { case IF_EQU: result = (result == 0); break; @@ -136,6 +152,9 @@ } } } + + cmd_free(Left); + cmd_free(Right);
if (result ^ ((Cmd->If.Flags & IFFLAG_NEGATE) != 0)) {
Modified: trunk/reactos/base/shell/cmd/redir.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/redir.c?rev=... ============================================================================== --- trunk/reactos/base/shell/cmd/redir.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/redir.c [iso-8859-1] Fri Feb 13 19:13:17 2009 @@ -54,7 +54,7 @@ PerformRedirection(REDIRECTION *RedirList) { REDIRECTION *Redir; - TCHAR Filename[MAX_PATH]; + LPTSTR Filename; HANDLE hNew; UINT DupNumber; static SECURITY_ATTRIBUTES SecAttr = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; @@ -78,8 +78,9 @@
for (Redir = RedirList; Redir; Redir = Redir->Next) { - *Filename = _T('\0'); - _tcsncat(Filename, Redir->Filename, MAX_PATH - 1); + Filename = DoDelayedExpansion(Redir->Filename); + if (!Filename) + goto redir_error; StripQuotes(Filename);
if (*Filename == _T('&')) @@ -112,6 +113,8 @@ { ConErrResPrintf(Redir->Type == REDIR_READ ? STRING_CMD_ERROR1 : STRING_CMD_ERROR3, Filename); + cmd_free(Filename); +redir_error: /* Undo all the redirections before this one */ UndoRedirection(RedirList, Redir); return FALSE; @@ -123,6 +126,7 @@ SetHandle(Redir->Number, hNew);
TRACE("%d redirected to: %s\n", Redir->Number, debugstr_aw(Filename)); + cmd_free(Filename); } return TRUE; }