ShellPkg/for: Fix potential null pointer deference
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel1CommandsLib / For.c
index 006ce6c..9824977 100644 (file)
@@ -1,7 +1,8 @@
 /** @file\r
   Main file for endfor and for shell level 1 functions.\r
 \r
-  Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
+  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -24,7 +25,6 @@
   @retval FALSE   The number is not valid.\r
 **/\r
 BOOLEAN\r
-EFIAPI\r
 ShellIsValidForNumber (\r
   IN CONST CHAR16 *Number\r
   )\r
@@ -42,7 +42,7 @@ ShellIsValidForNumber (
   }\r
 \r
   if (StrLen(Number) >= 7) {\r
-    if (StrStr(Number, L" ") != NULL && (StrStr(Number, L" ") - Number) >= 7) {\r
+    if ((StrStr(Number, L" ") == NULL) || (((StrStr(Number, L" ") != NULL) && (StrStr(Number, L" ") - Number) >= 7))) {\r
       return (FALSE);\r
     }\r
   }\r
@@ -69,24 +69,36 @@ ShellCommandRunEndFor (
 {\r
   EFI_STATUS          Status;\r
   BOOLEAN             Found;\r
+  SCRIPT_FILE         *CurrentScriptFile;\r
 \r
   Status = CommandInit();\r
   ASSERT_EFI_ERROR(Status);\r
 \r
   if (!gEfiShellProtocol->BatchIsActive()) {\r
-    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"EndFor");\r
+    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"endfor");\r
     return (SHELL_UNSUPPORTED);\r
   }\r
 \r
   if (gEfiShellParametersProtocol->Argc > 1) {\r
-    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle);\r
+    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle, L"endfor");\r
     return (SHELL_INVALID_PARAMETER);\r
   }\r
 \r
   Found = MoveToTag(GetPreviousNode, L"for", L"endfor", NULL, ShellCommandGetCurrentScriptFile(), FALSE, FALSE, FALSE);\r
 \r
   if (!Found) {\r
-    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"For", L"EndFor", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);\r
+    CurrentScriptFile = ShellCommandGetCurrentScriptFile();\r
+    ShellPrintHiiEx(\r
+      -1, \r
+      -1, \r
+      NULL, \r
+      STRING_TOKEN (STR_SYNTAX_NO_MATCHING), \r
+      gShellLevel1HiiHandle, \r
+      L"For", \r
+      L"EndFor", \r
+      CurrentScriptFile!=NULL\r
+        && CurrentScriptFile->CurrentCommand!=NULL\r
+          ? CurrentScriptFile->CurrentCommand->Line:0);\r
     return (SHELL_NOT_FOUND);\r
   }\r
   return (SHELL_SUCCESS);\r
@@ -108,15 +120,14 @@ typedef struct {
 /**\r
   Update the value of a given alias on the list.  If the alias is not there then add it.\r
 \r
-  @param[in] Alias              The alias to test for.\r
-  @param[in] CommandString      The updated command string.\r
-  @param[in,out] List           The list to search.\r
+  @param[in] Alias               The alias to test for.\r
+  @param[in] CommandString       The updated command string.\r
+  @param[in, out] List           The list to search.\r
 \r
   @retval EFI_SUCCESS           The operation was completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  There was not enough free memory.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 InternalUpdateAliasOnList(\r
   IN CONST CHAR16       *Alias,\r
   IN CONST CHAR16       *CommandString,\r
@@ -172,7 +183,6 @@ InternalUpdateAliasOnList(
   @retval FALSE                 The alias is not on the list.\r
 **/\r
 BOOLEAN\r
-EFIAPI\r
 InternalIsAliasOnList(\r
   IN CONST CHAR16       *Alias,\r
   IN CONST LIST_ENTRY   *List\r
@@ -204,11 +214,10 @@ InternalIsAliasOnList(
 /**\r
   Remove an alias from the given list.\r
 \r
-  @param[in] Alias              The alias to remove.\r
-  @param[in,out] List           The list to search.\r
+  @param[in] Alias               The alias to remove.\r
+  @param[in, out] List           The list to search.\r
 **/\r
 BOOLEAN\r
-EFIAPI\r
 InternalRemoveAliasFromList(\r
   IN CONST CHAR16       *Alias,\r
   IN OUT LIST_ENTRY     *List\r
@@ -241,6 +250,28 @@ InternalRemoveAliasFromList(
   return (FALSE);\r
 }\r
 \r
+/**\r
+  Function to determine whether a string is decimal or hex representation of a number\r
+  and return the number converted from the string.\r
+\r
+  @param[in] String   String representation of a number\r
+\r
+  @return             the number\r
+  @retval (UINTN)(-1) An error ocurred.\r
+**/\r
+UINTN\r
+ReturnUintn(\r
+  IN CONST CHAR16 *String\r
+  )\r
+{\r
+  UINT64        RetVal;\r
+\r
+  if (!EFI_ERROR(ShellConvertStringToUint64(String, &RetVal, FALSE, TRUE))) {\r
+    return ((UINTN)RetVal);\r
+  }\r
+  return ((UINTN)(-1));\r
+}\r
+\r
 /**\r
   Function for 'for' command.\r
 \r
@@ -259,6 +290,7 @@ ShellCommandRunFor (
   SCRIPT_FILE         *CurrentScriptFile;\r
   CHAR16              *ArgSet;\r
   CHAR16              *ArgSetWalker;\r
+  CHAR16              *Parameter;\r
   UINTN               ArgSize;\r
   UINTN               LoopVar;\r
   SHELL_FOR_INFO      *Info;\r
@@ -274,6 +306,7 @@ ShellCommandRunFor (
   ShellStatus         = SHELL_SUCCESS;\r
   ArgSetWalker        = NULL;\r
   TempString          = NULL;\r
+  Parameter           = NULL;\r
   FirstPass           = FALSE;\r
 \r
   //\r
@@ -286,26 +319,34 @@ ShellCommandRunFor (
   ASSERT_EFI_ERROR(Status);\r
 \r
   if (!gEfiShellProtocol->BatchIsActive()) {\r
-    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"For");\r
+    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"for");\r
     return (SHELL_UNSUPPORTED);\r
   }\r
 \r
   if (gEfiShellParametersProtocol->Argc < 4) {\r
-    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel1HiiHandle);\r
+    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel1HiiHandle, L"for");\r
     return (SHELL_INVALID_PARAMETER);\r
   }\r
 \r
   CurrentScriptFile = ShellCommandGetCurrentScriptFile();\r
   ASSERT(CurrentScriptFile != NULL);\r
 \r
-  if (CurrentScriptFile->CurrentCommand->Data == NULL) {\r
+  if ((CurrentScriptFile->CurrentCommand != NULL) && (CurrentScriptFile->CurrentCommand->Data == NULL)) {\r
     FirstPass = TRUE;\r
 \r
     //\r
     // Make sure that an End exists.\r
     //\r
     if (!MoveToTag(GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, TRUE, FALSE)) {\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"EndFor", L"For", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);\r
+      ShellPrintHiiEx(\r
+        -1, \r
+        -1, \r
+        NULL, \r
+        STRING_TOKEN (STR_SYNTAX_NO_MATCHING), \r
+        gShellLevel1HiiHandle, \r
+        L"EndFor", \r
+        L"For", \r
+        CurrentScriptFile->CurrentCommand->Line);\r
       return (SHELL_DEVICE_ERROR);\r
     }\r
 \r
@@ -326,11 +367,6 @@ ShellCommandRunFor (
         gEfiShellParametersProtocol->Argv[2]) == 0) {\r
       for (LoopVar = 0x3 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {\r
         ASSERT((ArgSet == NULL && ArgSize == 0) || (ArgSet != NULL));\r
-        if (ArgSet == NULL) {\r
-  //        ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);\r
-        } else {\r
-          ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" \"", 0);\r
-        }\r
         if (StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"*") != NULL\r
           ||StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"?") != NULL\r
           ||StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"[") != NULL\r
@@ -338,7 +374,9 @@ ShellCommandRunFor (
           FileList = NULL;\r
           Status = ShellOpenFileMetaArg ((CHAR16*)gEfiShellParametersProtocol->Argv[LoopVar], EFI_FILE_MODE_READ, &FileList);\r
           if (EFI_ERROR(Status) || FileList == NULL || IsListEmpty(&FileList->Link)) {\r
+            ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" \"", 0);\r
             ArgSet = StrnCatGrow(&ArgSet, &ArgSize, gEfiShellParametersProtocol->Argv[LoopVar], 0);\r
+            ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);\r
           } else {\r
             for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link)\r
               ;  !IsNull(&FileList->Link, &Node->Link)\r
@@ -351,39 +389,58 @@ ShellCommandRunFor (
             ShellCloseFileMetaArg(&FileList);\r
           }\r
         } else {\r
-          ArgSet = StrnCatGrow(&ArgSet, &ArgSize, gEfiShellParametersProtocol->Argv[LoopVar], 0);\r
+          Parameter = gEfiShellParametersProtocol->Argv[LoopVar];\r
+          if (Parameter[0] == L'\"' && Parameter[StrLen(Parameter)-1] == L'\"') {\r
+            ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" ", 0);\r
+            ArgSet = StrnCatGrow(&ArgSet, &ArgSize, Parameter, 0);\r
+          } else {\r
+            ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" \"", 0);\r
+            ArgSet = StrnCatGrow(&ArgSet, &ArgSize, Parameter, 0);\r
+            ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);\r
+          }\r
         }\r
-        ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);\r
       }\r
-      //\r
-      // set up for an 'in' for loop\r
-      //\r
-      NewSize = StrSize(ArgSet);\r
-      NewSize += sizeof(SHELL_FOR_INFO)+StrSize(gEfiShellParametersProtocol->Argv[1]);\r
-      Info = AllocateZeroPool(NewSize);\r
-      ASSERT(Info != NULL);\r
-      Info->Signature = SHELL_FOR_INFO_SIGNATURE;\r
-      CopyMem(Info->Set, ArgSet, StrSize(ArgSet));\r
-      NewSize = StrSize(gEfiShellParametersProtocol->Argv[1]);\r
-      CopyMem(Info->Set+(StrSize(ArgSet)/sizeof(Info->Set[0])), gEfiShellParametersProtocol->Argv[1], NewSize);\r
-      Info->ReplacementName = Info->Set+StrSize(ArgSet)/sizeof(Info->Set[0]);\r
-      Info->CurrentValue  = (CHAR16*)Info->Set;\r
-      Info->Step          = 0;\r
-      Info->Current       = 0;\r
-      Info->End           = 0;\r
-\r
-      if (InternalIsAliasOnList(Info->ReplacementName, &CurrentScriptFile->SubstList)) {\r
-        Info->RemoveSubstAlias  = FALSE;\r
+      if (ArgSet == NULL) {\r
+        ShellStatus = SHELL_OUT_OF_RESOURCES;\r
       } else {\r
-        Info->RemoveSubstAlias  = TRUE;\r
+        //\r
+        // set up for an 'in' for loop\r
+        //\r
+        NewSize = StrSize(ArgSet);\r
+        NewSize += sizeof(SHELL_FOR_INFO)+StrSize(gEfiShellParametersProtocol->Argv[1]);\r
+        Info = AllocateZeroPool(NewSize);\r
+        if (Info == NULL) {\r
+          FreePool (ArgSet);\r
+          return SHELL_OUT_OF_RESOURCES;\r
+        }\r
+        Info->Signature = SHELL_FOR_INFO_SIGNATURE;\r
+        CopyMem(Info->Set, ArgSet, StrSize(ArgSet));\r
+        NewSize = StrSize(gEfiShellParametersProtocol->Argv[1]);\r
+        CopyMem(Info->Set+(StrSize(ArgSet)/sizeof(Info->Set[0])), gEfiShellParametersProtocol->Argv[1], NewSize);\r
+        Info->ReplacementName = Info->Set+StrSize(ArgSet)/sizeof(Info->Set[0]);\r
+        Info->CurrentValue  = (CHAR16*)Info->Set;\r
+        Info->Step          = 0;\r
+        Info->Current       = 0;\r
+        Info->End           = 0;\r
+\r
+        if (InternalIsAliasOnList(Info->ReplacementName, &CurrentScriptFile->SubstList)) {\r
+          Info->RemoveSubstAlias  = FALSE;\r
+        } else {\r
+          Info->RemoveSubstAlias  = TRUE;\r
+        }\r
+        CurrentScriptFile->CurrentCommand->Data = Info;\r
       }\r
-      CurrentScriptFile->CurrentCommand->Data = Info;\r
     } else if (gUnicodeCollation->StriColl(\r
         gUnicodeCollation,\r
         L"run",\r
         gEfiShellParametersProtocol->Argv[2]) == 0) {\r
       for (LoopVar = 0x3 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {\r
         ASSERT((ArgSet == NULL && ArgSize == 0) || (ArgSet != NULL));\r
+        if (StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L")") != NULL &&\r
+            (LoopVar + 1) < gEfiShellParametersProtocol->Argc\r
+           ) {\r
+          return (SHELL_INVALID_PARAMETER);\r
+        }\r
         if (ArgSet == NULL) {\r
 //        ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);\r
         } else {\r
@@ -392,108 +449,168 @@ ShellCommandRunFor (
         ArgSet = StrnCatGrow(&ArgSet, &ArgSize, gEfiShellParametersProtocol->Argv[LoopVar], 0);\r
 //        ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" ", 0);\r
       }\r
-      //\r
-      // set up for a 'run' for loop\r
-      //\r
-      Info = AllocateZeroPool(sizeof(SHELL_FOR_INFO)+StrSize(gEfiShellParametersProtocol->Argv[1]));\r
-      ASSERT(Info != NULL);\r
-      CopyMem(Info->Set, gEfiShellParametersProtocol->Argv[1], StrSize(gEfiShellParametersProtocol->Argv[1]));\r
-      Info->ReplacementName = Info->Set;\r
-      Info->CurrentValue    = NULL;\r
-      ArgSetWalker            = ArgSet;\r
-      if (ArgSetWalker[0] != L'(') {\r
-        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);\r
-        ShellStatus = SHELL_INVALID_PARAMETER;\r
+      if (ArgSet == NULL) {\r
+        ShellStatus = SHELL_OUT_OF_RESOURCES;\r
       } else {\r
-        TempSpot = StrStr(ArgSetWalker, L")");\r
-        if (TempSpot != NULL) {\r
-          TempString = TempSpot+1;\r
-          if (*(TempString) != CHAR_NULL) {\r
-            while(TempString != NULL && *TempString == L' ') {\r
-              TempString++;\r
-            }\r
-            if (StrLen(TempString) > 0) {\r
-              TempSpot = NULL;\r
-            }\r
-          }\r
+        //\r
+        // set up for a 'run' for loop\r
+        //\r
+        Info = AllocateZeroPool(sizeof(SHELL_FOR_INFO)+StrSize(gEfiShellParametersProtocol->Argv[1]));\r
+        if (Info == NULL) {\r
+          FreePool (ArgSet);\r
+          return SHELL_OUT_OF_RESOURCES;\r
         }\r
-        if (TempSpot == NULL) {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);\r
+        Info->Signature = SHELL_FOR_INFO_SIGNATURE;\r
+        CopyMem(Info->Set, gEfiShellParametersProtocol->Argv[1], StrSize(gEfiShellParametersProtocol->Argv[1]));\r
+        Info->ReplacementName = Info->Set;\r
+        Info->CurrentValue    = NULL;\r
+        ArgSetWalker            = ArgSet;\r
+        if (ArgSetWalker[0] != L'(') {\r
+          ShellPrintHiiEx(\r
+            -1, \r
+            -1, \r
+            NULL, \r
+            STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), \r
+            gShellLevel1HiiHandle, \r
+            ArgSet, \r
+            CurrentScriptFile->CurrentCommand->Line);\r
           ShellStatus = SHELL_INVALID_PARAMETER;\r
         } else {\r
-          *TempSpot = CHAR_NULL;\r
-          ArgSetWalker++;\r
-          while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') {\r
-            ArgSetWalker++;\r
+          TempSpot = StrStr(ArgSetWalker, L")");\r
+          if (TempSpot != NULL) {\r
+            TempString = TempSpot+1;\r
+            if (*(TempString) != CHAR_NULL) {\r
+              while(TempString != NULL && *TempString == L' ') {\r
+                TempString++;\r
+              }\r
+              if (StrLen(TempString) > 0) {\r
+                TempSpot = NULL;\r
+              }\r
+            }\r
           }\r
-          if (!ShellIsValidForNumber(ArgSetWalker)) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);\r
+          if (TempSpot == NULL) {\r
+            ShellPrintHiiEx(\r
+              -1, \r
+              -1, \r
+              NULL, \r
+              STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), \r
+              gShellLevel1HiiHandle, \r
+              CurrentScriptFile->CurrentCommand->Line);\r
             ShellStatus = SHELL_INVALID_PARAMETER;\r
           } else {\r
-            if (ArgSetWalker[0] == L'-') {\r
-              Info->Current = 0 - (INTN)ShellStrToUintn(ArgSetWalker+1);\r
-            } else {\r
-              Info->Current = (INTN)ShellStrToUintn(ArgSetWalker);\r
-            }\r
-            ArgSetWalker  = StrStr(ArgSetWalker, L" ");\r
+            *TempSpot = CHAR_NULL;\r
+            ArgSetWalker++;\r
             while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') {\r
               ArgSetWalker++;\r
             }\r
-            if (ArgSetWalker == NULL || *ArgSetWalker == CHAR_NULL || !ShellIsValidForNumber(ArgSetWalker)){\r
-              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);\r
+            if (!ShellIsValidForNumber(ArgSetWalker)) {\r
+              ShellPrintHiiEx(\r
+                -1, \r
+                -1, \r
+                NULL, \r
+                STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), \r
+                gShellLevel1HiiHandle, \r
+                ArgSet, \r
+                CurrentScriptFile->CurrentCommand->Line);\r
               ShellStatus = SHELL_INVALID_PARAMETER;\r
             } else {\r
               if (ArgSetWalker[0] == L'-') {\r
-                Info->End = 0 - (INTN)ShellStrToUintn(ArgSetWalker+1);\r
-              } else {\r
-                Info->End = (INTN)ShellStrToUintn(ArgSetWalker);\r
-              }\r
-              if (Info->Current < Info->End) {\r
-                Info->Step            = 1;\r
+                Info->Current = 0 - (INTN)ReturnUintn(ArgSetWalker+1);\r
               } else {\r
-                Info->Step            = -1;\r
+                Info->Current = (INTN)ReturnUintn(ArgSetWalker);\r
               }\r
-\r
               ArgSetWalker  = StrStr(ArgSetWalker, L" ");\r
               while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') {\r
                 ArgSetWalker++;\r
               }\r
-              if (ArgSetWalker != NULL && *ArgSetWalker != CHAR_NULL) {\r
-                if (ArgSetWalker == NULL || *ArgSetWalker == CHAR_NULL || !ShellIsValidForNumber(ArgSetWalker)){\r
-                  ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);\r
-                  ShellStatus = SHELL_INVALID_PARAMETER;\r
+              if (ArgSetWalker == NULL || *ArgSetWalker == CHAR_NULL || !ShellIsValidForNumber(ArgSetWalker)){\r
+                ShellPrintHiiEx(\r
+                  -1, \r
+                  -1, \r
+                  NULL, \r
+                  STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), \r
+                  gShellLevel1HiiHandle, \r
+                  ArgSet, \r
+                  CurrentScriptFile->CurrentCommand->Line);\r
+                ShellStatus = SHELL_INVALID_PARAMETER;\r
+              } else {\r
+                if (ArgSetWalker[0] == L'-') {\r
+                  Info->End = 0 - (INTN)ReturnUintn(ArgSetWalker+1);\r
                 } else {\r
-                  if (*ArgSetWalker == L')') {\r
-                    ASSERT(Info->Step == 1 || Info->Step == -1);\r
+                  Info->End = (INTN)ReturnUintn(ArgSetWalker);\r
+                }\r
+                if (Info->Current < Info->End) {\r
+                  Info->Step            = 1;\r
+                } else {\r
+                  Info->Step            = -1;\r
+                }\r
+\r
+                ArgSetWalker  = StrStr(ArgSetWalker, L" ");\r
+                while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') {\r
+                  ArgSetWalker++;\r
+                }\r
+                if (ArgSetWalker != NULL && *ArgSetWalker != CHAR_NULL) {\r
+                  if (ArgSetWalker == NULL || *ArgSetWalker == CHAR_NULL || !ShellIsValidForNumber(ArgSetWalker)){\r
+                    ShellPrintHiiEx(\r
+                      -1, \r
+                      -1, \r
+                      NULL, \r
+                      STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), \r
+                      gShellLevel1HiiHandle, \r
+                      ArgSet, \r
+                      CurrentScriptFile->CurrentCommand->Line);\r
+                    ShellStatus = SHELL_INVALID_PARAMETER;\r
                   } else {\r
-                    if (ArgSetWalker[0] == L'-') {\r
-                      Info->Step = 0 - (INTN)ShellStrToUintn(ArgSetWalker+1);\r
+                    if (*ArgSetWalker == L')') {\r
+                      ASSERT(Info->Step == 1 || Info->Step == -1);\r
                     } else {\r
-                      Info->Step = (INTN)ShellStrToUintn(ArgSetWalker);\r
-                    }\r
-\r
-                    if (StrStr(ArgSetWalker, L" ") != NULL) {\r
-                      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);\r
-                      ShellStatus = SHELL_INVALID_PARAMETER;\r
+                      if (ArgSetWalker[0] == L'-') {\r
+                        Info->Step = 0 - (INTN)ReturnUintn(ArgSetWalker+1);\r
+                      } else {\r
+                        Info->Step = (INTN)ReturnUintn(ArgSetWalker);\r
+                      }\r
+\r
+                      if (StrStr(ArgSetWalker, L" ") != NULL) {\r
+                        ShellPrintHiiEx(\r
+                          -1, \r
+                          -1, \r
+                          NULL, \r
+                          STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), \r
+                          gShellLevel1HiiHandle, \r
+                          ArgSet, \r
+                          CurrentScriptFile->CurrentCommand->Line);\r
+                        ShellStatus = SHELL_INVALID_PARAMETER;\r
+                      }\r
                     }\r
                   }\r
+                  \r
                 }\r
-                \r
               }\r
             }\r
           }\r
         }\r
-      }\r
-      if (ShellStatus == SHELL_SUCCESS) {\r
-        if (InternalIsAliasOnList(Info->ReplacementName, &CurrentScriptFile->SubstList)) {\r
-          Info->RemoveSubstAlias  = FALSE;\r
-        } else {\r
-          Info->RemoveSubstAlias  = TRUE;\r
+        if (ShellStatus == SHELL_SUCCESS) {\r
+          if (InternalIsAliasOnList(Info->ReplacementName, &CurrentScriptFile->SubstList)) {\r
+            Info->RemoveSubstAlias  = FALSE;\r
+          } else {\r
+            Info->RemoveSubstAlias  = TRUE;\r
+          }\r
+        }\r
+        if (CurrentScriptFile->CurrentCommand != NULL) {\r
+          CurrentScriptFile->CurrentCommand->Data = Info;\r
         }\r
       }\r
-      CurrentScriptFile->CurrentCommand->Data = Info;\r
     } else {\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);\r
+      ShellPrintHiiEx(\r
+        -1, \r
+        -1, \r
+        NULL, \r
+        STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), \r
+        gShellLevel1HiiHandle, \r
+        ArgSet, \r
+        CurrentScriptFile!=NULL \r
+          && CurrentScriptFile->CurrentCommand!=NULL\r
+          ? CurrentScriptFile->CurrentCommand->Line:0);\r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
     }\r
   } else {\r
@@ -504,11 +621,18 @@ ShellCommandRunFor (
     ASSERT(ArgSet       == NULL);\r
   }\r
 \r
-  Info = (SHELL_FOR_INFO*)CurrentScriptFile->CurrentCommand->Data;\r
-  if (CurrentScriptFile->CurrentCommand->Reset) {\r
-    Info->CurrentValue  = (CHAR16*)Info->Set;\r
-    FirstPass = TRUE;\r
-    CurrentScriptFile->CurrentCommand->Reset = FALSE;\r
+  if (CurrentScriptFile != NULL && CurrentScriptFile->CurrentCommand != NULL) {\r
+    Info = (SHELL_FOR_INFO*)CurrentScriptFile->CurrentCommand->Data;\r
+    if (CurrentScriptFile->CurrentCommand->Reset) {\r
+      if (Info != NULL) {\r
+        Info->CurrentValue = (CHAR16*)Info->Set;\r
+      }\r
+      FirstPass = TRUE;\r
+      CurrentScriptFile->CurrentCommand->Reset = FALSE;\r
+    }\r
+  } else {\r
+    ShellStatus = SHELL_UNSUPPORTED;\r
+    Info = NULL;\r
   }\r
   if (ShellStatus == SHELL_SUCCESS) {\r
     ASSERT(Info != NULL);\r
@@ -534,7 +658,17 @@ ShellCommandRunFor (
         // find the matching endfor (we're done with the loop)\r
         //\r
         if (!MoveToTag(GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, FALSE, FALSE)) {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"EndFor", L"For", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);\r
+          ShellPrintHiiEx(\r
+            -1, \r
+            -1, \r
+            NULL, \r
+            STRING_TOKEN (STR_SYNTAX_NO_MATCHING), \r
+            gShellLevel1HiiHandle, \r
+            L"EndFor", \r
+            L"For", \r
+            CurrentScriptFile!=NULL \r
+              && CurrentScriptFile->CurrentCommand!=NULL\r
+              ? CurrentScriptFile->CurrentCommand->Line:0);\r
           ShellStatus = SHELL_DEVICE_ERROR;\r
         }\r
         if (Info->RemoveSubstAlias) {\r
@@ -551,12 +685,9 @@ ShellCommandRunFor (
       //\r
       ASSERT(Info->Set != NULL);\r
       if (Info->CurrentValue != NULL && *Info->CurrentValue != CHAR_NULL) {\r
-        if (Info->CurrentValue[0] == L'\"') {\r
+        if (Info->CurrentValue[0] == L' ') {\r
           Info->CurrentValue++;\r
         }\r
-//        while (Info->CurrentValue[0] == L' ') {\r
-//          Info->CurrentValue++;\r
-//        }\r
         if (Info->CurrentValue[0] == L'\"') {\r
           Info->CurrentValue++;\r
         }\r
@@ -565,34 +696,41 @@ ShellCommandRunFor (
         //\r
         ASSERT(TempString == NULL);\r
         TempString = StrnCatGrow(&TempString, NULL, Info->CurrentValue, 0);\r
-        TempSpot   = StrStr(TempString, L"\" \"");\r
-        if (TempSpot != NULL) {\r
-          *TempSpot = CHAR_NULL;\r
-        }\r
-        while (TempString[StrLen(TempString)-1] == L'\"') {\r
-          TempString[StrLen(TempString)-1] = CHAR_NULL;\r
-        }\r
-        InternalUpdateAliasOnList(Info->ReplacementName, TempString, &CurrentScriptFile->SubstList);\r
-        Info->CurrentValue += StrLen(TempString);\r
+        if (TempString == NULL) {\r
+          ShellStatus = SHELL_OUT_OF_RESOURCES;\r
+        } else {\r
+          TempSpot   = StrStr(TempString, L"\" \"");\r
+          if (TempSpot != NULL) {\r
+            *TempSpot = CHAR_NULL;\r
+          }\r
+          while (TempString[StrLen(TempString)-1] == L'\"') {\r
+            TempString[StrLen(TempString)-1] = CHAR_NULL;\r
+          }\r
+          InternalUpdateAliasOnList(Info->ReplacementName, TempString, &CurrentScriptFile->SubstList);\r
+          Info->CurrentValue += StrLen(TempString);\r
 \r
-        if (Info->CurrentValue[0] == L'\"') {\r
-          Info->CurrentValue++;\r
-        }\r
-        while (Info->CurrentValue[0] == L' ') {\r
-          Info->CurrentValue++;\r
-        }\r
-        if (Info->CurrentValue[0] == L'\"') {\r
-          Info->CurrentValue++;\r
+          if (Info->CurrentValue[0] == L'\"') {\r
+            Info->CurrentValue++;\r
+          }\r
+          FreePool(TempString);\r
         }\r
-        FreePool(TempString);\r
-\r
       } else {\r
         CurrentScriptFile->CurrentCommand->Data = NULL;\r
         //\r
         // find the matching endfor (we're done with the loop)\r
         //\r
         if (!MoveToTag(GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, FALSE, FALSE)) {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"EndFor", L"For", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);\r
+          ShellPrintHiiEx(\r
+            -1, \r
+            -1, \r
+            NULL, \r
+            STRING_TOKEN (STR_SYNTAX_NO_MATCHING), \r
+            gShellLevel1HiiHandle, \r
+            L"EndFor", \r
+            L"For", \r
+            CurrentScriptFile!=NULL \r
+              && CurrentScriptFile->CurrentCommand!=NULL\r
+              ? CurrentScriptFile->CurrentCommand->Line:0);\r
           ShellStatus = SHELL_DEVICE_ERROR;\r
         }\r
         if (Info->RemoveSubstAlias) {\r