]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ShellPkg: refactor elimination of non-replaced environment variables
authorJaben Carsey <jaben.carsey@intel.com>
Wed, 12 Feb 2014 18:27:07 +0000 (18:27 +0000)
committerjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 12 Feb 2014 18:27:07 +0000 (18:27 +0000)
This changes how non-replaced environment variables are found and eliminated from the command line.  This new method makes sure that the found environment variables are not using escaped characters and that they do not stretch over quoted strings

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jaben Carsey <jaben.carsey@intel.com>
Reviewed-by: Erik Bjorge <erik.c.bjorge@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15242 6f19259b-4bc3-4df7-8a09-765794883524

ShellPkg/Application/Shell/Shell.c

index 2d5c89aadfe9e64a02e0e4b3559a2428fb02273a..ba3be3f6c344236e393bc9a9174ddfa1a06d5725 100644 (file)
@@ -1276,6 +1276,113 @@ ShellConvertAlias(
   return (EFI_SUCCESS);\r
 }\r
 \r
+/**\r
+  Parse for the next instance of one string within another string. Can optionally make sure that \r
+  the string was not escaped (^ character) per the shell specification.\r
+\r
+  @param[in] SourceString             The string to search within\r
+  @param[in] FindString               The string to look for\r
+  @param[in] CheckForEscapeCharacter  TRUE to skip escaped instances of FinfString, otherwise will return even escaped instances\r
+**/\r
+CHAR16*\r
+EFIAPI\r
+FindNextInstance(\r
+  IN CONST CHAR16   *SourceString,\r
+  IN CONST CHAR16   *FindString,\r
+  IN CONST BOOLEAN  CheckForEscapeCharacter\r
+  )\r
+{\r
+  CHAR16 *Temp;\r
+  if (SourceString == NULL) {\r
+    return (NULL);\r
+  }\r
+  Temp = StrStr(SourceString, FindString);\r
+\r
+  //\r
+  // If nothing found, or we dont care about escape characters\r
+  //\r
+  if (Temp == NULL || !CheckForEscapeCharacter) {\r
+    return (Temp);\r
+  }\r
+\r
+  //\r
+  // If we found an escaped character, try again on the remainder of the string\r
+  //\r
+  if ((Temp > (SourceString)) && *(Temp-1) == L'^') {\r
+    return FindNextInstance(Temp+1, FindString, CheckForEscapeCharacter);\r
+  }\r
+\r
+  //\r
+  // we found the right character\r
+  //\r
+  return (Temp);\r
+}\r
+\r
+/**\r
+  This function will eliminate unreplaced (and therefore non-found) environment variables.\r
+\r
+  @param[in,out] CmdLine   The command line to update.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+StripUnreplacedEnvironmentVariables(\r
+  IN OUT CHAR16 *CmdLine\r
+  )\r
+{\r
+  CHAR16 *FirstPercent;\r
+  CHAR16 *FirstQuote;\r
+  CHAR16 *SecondPercent;\r
+  CHAR16 *SecondQuote;\r
+  CHAR16 *CurrentLocator;\r
+\r
+  for (CurrentLocator = CmdLine ; CurrentLocator != NULL ; ) {\r
+    FirstQuote = FindNextInstance(CurrentLocator, L"\"", TRUE);\r
+    FirstPercent = FindNextInstance(CurrentLocator, L"%", TRUE);\r
+    SecondPercent = FirstPercent!=NULL?FindNextInstance(FirstPercent+1, L"%", TRUE):NULL;\r
+    if (FirstPercent == NULL || SecondPercent == NULL) {\r
+      //\r
+      // If we ever dont have 2 % we are done.\r
+      //\r
+      break;\r
+    }\r
+\r
+    if (FirstQuote < FirstPercent) {\r
+      SecondQuote = FirstQuote!= NULL?FindNextInstance(FirstQuote+1, L"\"", TRUE):NULL;\r
+      //\r
+      // Quote is first found\r
+      //\r
+\r
+      if (SecondQuote < FirstPercent) {\r
+        //\r
+        // restart after the pair of "\r
+        //\r
+        CurrentLocator = SecondQuote + 1;\r
+      } else /* FirstPercent < SecondQuote */{\r
+        //\r
+        // Restart on the first percent\r
+        //\r
+        CurrentLocator = FirstPercent;\r
+      }\r
+      continue;\r
+    }\r
+    ASSERT(FirstPercent < FirstQuote);\r
+    if (SecondPercent < FirstQuote) {\r
+      //\r
+      // We need to remove from FirstPercent to SecondPercent\r
+      //\r
+      CopyMem(FirstPercent, SecondPercent + 1, StrSize(SecondPercent + 1));\r
+\r
+      //\r
+      // dont need to update the locator.  both % characters are gone.\r
+      //\r
+      continue;\r
+    }\r
+    ASSERT(FirstQuote < SecondPercent);\r
+    CurrentLocator = FirstQuote;\r
+  }\r
+  return (EFI_SUCCESS);\r
+}\r
+\r
 /**\r
   Function allocates a new command line and replaces all instances of environment\r
   variable names that are correctly preset to their values.\r
@@ -1298,7 +1405,6 @@ ShellConvertVariables (
   CHAR16              *NewCommandLine1;\r
   CHAR16              *NewCommandLine2;\r
   CHAR16              *Temp;\r
-  CHAR16              *Temp2;\r
   UINTN               ItemSize;\r
   CHAR16              *ItemTemp;\r
   SCRIPT_FILE         *CurrentScriptFile;\r
@@ -1391,39 +1497,7 @@ ShellConvertVariables (
     //\r
     // Remove non-existant environment variables in scripts only\r
     //\r
-    for (Temp = NewCommandLine1 ; Temp != NULL ; ) {\r
-      Temp = StrStr(Temp, L"%");\r
-      if (Temp == NULL) {\r
-        break;\r
-      }\r
-      while (*(Temp - 1) == L'^') {\r
-        Temp = StrStr(Temp + 1, L"%");\r
-        if (Temp == NULL) {\r
-          break;\r
-       }\r
-      }\r
-      if (Temp == NULL) {\r
-        break;\r
-      }\r
-      \r
-      Temp2 = StrStr(Temp + 1, L"%");\r
-      if (Temp2 == NULL) {\r
-        break;\r
-      }\r
-      while (*(Temp2 - 1) == L'^') {\r
-        Temp2 = StrStr(Temp2 + 1, L"%");\r
-        if (Temp2 == NULL) {\r
-          break;\r
-        }\r
-      }\r
-      if (Temp2 == NULL) {\r
-        break;\r
-      }\r
-      \r
-      Temp2++;\r
-      CopyMem(Temp, Temp2, StrSize(Temp2));\r
-    }\r
-\r
+    StripUnreplacedEnvironmentVariables(NewCommandLine1);\r
   }\r
 \r
   //\r