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=3…
==============================================================================
--- 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=3…
==============================================================================
--- 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=39…
==============================================================================
--- 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;
}