]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Application/Shell/Shell.c
Add the comment for function 'IsValidSplit' in 'Shell.c'. Add code to check whether...
[mirror_edk2.git] / ShellPkg / Application / Shell / Shell.c
index fcf4962e82560ca15a64393446e9d29a2369b806..44469baaed1f6de3e312349e7153f3dba8e40118 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   This is THE shell (application)\r
 \r
-  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>\r
   Copyright (c) 2013, Hewlett-Packard Development Company, L.P.\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -71,9 +71,9 @@ STATIC CONST CHAR16 mExecutableExtensions[] = L".NSH;.EFI";
 STATIC CONST CHAR16 mStartupScript[]        = L"startup.nsh";\r
 \r
 /**\r
-  Cleans off leading and trailing spaces and tabs\r
+  Cleans off leading and trailing spaces and tabs.\r
 \r
-  @param[in] String pointer to the string to trim them off\r
+  @param[in] String pointer to the string to trim them off.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -107,8 +107,7 @@ TrimSpaces(
 \r
   @retval                 A pointer to the | character in CmdLine or NULL if not present.\r
 **/\r
-CONST\r
-CHAR16*\r
+CONST CHAR16*\r
 EFIAPI\r
 FindSplit(\r
   IN CONST CHAR16 *CmdLine\r
@@ -1432,13 +1431,12 @@ RunSplitCommand(
 \r
 /**\r
   Take the original command line, substitute any variables, free \r
-  the original string, return the modified copy\r
+  the original string, return the modified copy.\r
 \r
-  @param[in,out] CmdLine  pointer to the command line to update\r
-  @param[out]CmdName      upon successful return the name of the command to be run\r
+  @param[in] CmdLine  pointer to the command line to update.\r
 \r
-  @retval EFI_SUCCESS           the function was successful\r
-  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed\r
+  @retval EFI_SUCCESS           the function was successful.\r
+  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -1458,13 +1456,12 @@ ShellSubstituteVariables(
 \r
 /**\r
   Take the original command line, substitute any alias in the first group of space delimited characters, free \r
-  the original string, return the modified copy\r
+  the original string, return the modified copy.\r
 \r
-  @param[in] CmdLine  pointer to the command line to update\r
-  @param[out]CmdName  upon successful return the name of the command to be run\r
+  @param[in] CmdLine  pointer to the command line to update.\r
 \r
-  @retval EFI_SUCCESS           the function was successful\r
-  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed\r
+  @retval EFI_SUCCESS           the function was successful.\r
+  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -1530,13 +1527,13 @@ ShellSubstituteAliases(
 /**\r
   Takes the Argv[0] part of the command line and determine the meaning of it.\r
 \r
-  @param[in] CmdLine  pointer to the command line to update\r
+  @param[in] CmdName  pointer to the command line to update.\r
   \r
-  @retval INTERNAL_COMMAND    The name is an internal command\r
-  @retval FILE_SYS_CHANGE     the name is a file system change\r
-  @retval SCRIPT_FILE_NAME    the name is a NSH script file\r
-  @retval UNKNOWN_INVALID     the name is unknown\r
-  @retval EFI_APPLICATION     the name is an application (.EFI)\r
+  @retval Internal_Command    The name is an internal command.\r
+  @retval File_Sys_Change     the name is a file system change.\r
+  @retval Script_File_Name    the name is a NSH script file.\r
+  @retval Unknown_Invalid     the name is unknown.\r
+  @retval Efi_Application     the name is an application (.EFI).\r
 **/\r
 SHELL_OPERATION_TYPES\r
 EFIAPI\r
@@ -1553,7 +1550,7 @@ GetOperationType(
   // test for an internal command.\r
   //\r
   if (ShellCommandIsCommandOnList(CmdName)) {\r
-    return (INTERNAL_COMMAND);\r
+    return (Internal_Command);\r
   }\r
 \r
   //\r
@@ -1561,9 +1558,9 @@ GetOperationType(
   //\r
   if (CmdName[(StrLen(CmdName)-1)] == L':') {\r
     if (StrStr(CmdName, L" ") != NULL) {\r
-      return (UNKNOWN_INVALID);\r
+      return (Unknown_Invalid);\r
     }\r
-    return (FILE_SYS_CHANGE);\r
+    return (File_Sys_Change);\r
   }\r
 \r
   //\r
@@ -1578,7 +1575,7 @@ GetOperationType(
       TempLocation2 = mScriptExtension;\r
       if (StringNoCaseCompare((VOID*)(&TempLocation), (VOID*)(&TempLocation2)) == 0) {\r
         SHELL_FREE_NON_NULL(FileWithPath);\r
-        return (SCRIPT_FILE_NAME);\r
+        return (Script_File_Name);\r
       }\r
     }\r
 \r
@@ -1586,14 +1583,113 @@ GetOperationType(
     // Was a file, but not a script.  we treat this as an application.\r
     //\r
     SHELL_FREE_NON_NULL(FileWithPath);\r
-    return (EFI_APPLICATION);\r
+    return (Efi_Application);\r
   }\r
   \r
   SHELL_FREE_NON_NULL(FileWithPath);\r
   //\r
   // No clue what this is... return invalid flag...\r
   //\r
-  return (UNKNOWN_INVALID);\r
+  return (Unknown_Invalid);\r
+}\r
+\r
+/**\r
+  Determine if the first item in a command line is valid.\r
+\r
+  @param[in] CmdLine            The command line to parse.\r
+\r
+  @retval EFI_SUCCESS           The item is valid.\r
+  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.\r
+  @retval EFI_NOT_FOUND         The operation type is unknown or invalid.\r
+**/\r
+EFI_STATUS \r
+EFIAPI\r
+IsValidSplit(\r
+  IN CONST CHAR16 *CmdLine\r
+  )\r
+{\r
+  CHAR16        *Temp;\r
+  CHAR16        *FirstParameter;\r
+  CHAR16        *TempWalker;\r
+  EFI_STATUS    Status;\r
+\r
+  Temp           = NULL;\r
+\r
+  Temp = StrnCatGrow(&Temp, NULL, CmdLine, 0);\r
+  if (Temp == NULL) {\r
+    return (EFI_OUT_OF_RESOURCES);\r
+  }\r
+\r
+  FirstParameter = StrStr(Temp, L"|");\r
+  if (FirstParameter != NULL) {\r
+    *FirstParameter = CHAR_NULL;\r
+  }\r
+\r
+  FirstParameter = NULL;\r
+\r
+  //\r
+  // Process the command line\r
+  //\r
+  Status = ProcessCommandLineToFinal(&Temp);\r
+\r
+  if (!EFI_ERROR(Status)) {\r
+    FirstParameter = AllocateZeroPool(StrSize(CmdLine));\r
+    if (FirstParameter == NULL) {\r
+      SHELL_FREE_NON_NULL(Temp);\r
+      return (EFI_OUT_OF_RESOURCES);\r
+    }\r
+    TempWalker = (CHAR16*)Temp;\r
+    GetNextParameter(&TempWalker, &FirstParameter);\r
+\r
+    if (GetOperationType(FirstParameter) == Unknown_Invalid) {\r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);\r
+      SetLastError(SHELL_NOT_FOUND);\r
+      Status = EFI_NOT_FOUND;\r
+    }\r
+  }\r
+\r
+  SHELL_FREE_NON_NULL(Temp);\r
+  SHELL_FREE_NON_NULL(FirstParameter);\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Determine if a command line contains with a split contains only valid commands.\r
+\r
+  @param[in] CmdLine      The command line to parse.\r
+\r
+  @retval EFI_SUCCESS     CmdLine has only valid commands, application, or has no split.\r
+  @retval EFI_ABORTED     CmdLine has at least one invalid command or application.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VerifySplit(\r
+  IN CONST CHAR16 *CmdLine\r
+  )\r
+{\r
+  CONST CHAR16  *TempSpot;\r
+  EFI_STATUS    Status;\r
+\r
+  //\r
+  // Verify up to the pipe or end character\r
+  //\r
+  Status = IsValidSplit(CmdLine);\r
+  if (EFI_ERROR(Status)) {\r
+    return (Status);\r
+  }\r
+\r
+  //\r
+  // If this was the only item, then get out\r
+  //\r
+  if (!ContainsSplit(CmdLine)) {\r
+    return (EFI_SUCCESS);\r
+  }\r
+\r
+  //\r
+  // recurse to verify the next item\r
+  //\r
+  TempSpot = FindSplit(CmdLine)+1;\r
+  return (VerifySplit(TempSpot));\r
 }\r
 \r
 /**\r
@@ -1613,6 +1709,11 @@ ProcessNewSplitCommandLine(
   SPLIT_LIST                *Split;\r
   EFI_STATUS                Status;\r
 \r
+  Status = VerifySplit(CmdLine);\r
+  if (EFI_ERROR(Status)) {\r
+    return (Status);\r
+  }\r
+\r
   Split = NULL;\r
 \r
   //\r
@@ -1634,11 +1735,11 @@ ProcessNewSplitCommandLine(
 }\r
 \r
 /**\r
-  Handle a request to change the current file system\r
+  Handle a request to change the current file system.\r
 \r
-  @param[in] CmdLine  The passed in command line\r
+  @param[in] CmdLine  The passed in command line.\r
 \r
-  @retval EFI_SUCCESS The operation was successful\r
+  @retval EFI_SUCCESS The operation was successful.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -1721,14 +1822,14 @@ DoHelpUpdate(
 }\r
 \r
 /**\r
-  Function to update the shell variable "lasterror"\r
+  Function to update the shell variable "lasterror".\r
 \r
-  @param[in] ErrorCode      the error code to put into lasterror\r
+  @param[in] ErrorCode      the error code to put into lasterror.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 SetLastError(\r
-  IN CONST UINT64   ErrorCode\r
+  IN CONST SHELL_STATUS   ErrorCode\r
   )\r
 {\r
   CHAR16 LeString[19];\r
@@ -1754,7 +1855,7 @@ SetLastError(
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-ProcessCommandLineAliasVariable(\r
+ProcessCommandLineToFinal(\r
   IN OUT CHAR16 **CmdLine\r
   )\r
 {\r
@@ -1911,11 +2012,11 @@ RunCommandOrFile(
   DevPath           = NULL;\r
 \r
   switch (Type) {\r
-    case   INTERNAL_COMMAND:\r
+    case   Internal_Command:\r
       Status = RunInternalCommand(CmdLine, FirstParameter, ParamProtocol);\r
       break;\r
-    case   SCRIPT_FILE_NAME:\r
-    case   EFI_APPLICATION:\r
+    case   Script_File_Name:\r
+    case   Efi_Application:\r
       //\r
       // Process a fully qualified path\r
       //\r
@@ -1943,13 +2044,13 @@ RunCommandOrFile(
       //\r
       if (!EFI_ERROR(ShellIsDirectory(CommandWithPath))) {\r
         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);\r
-        SetLastError(EFI_NOT_FOUND);\r
+        SetLastError(SHELL_NOT_FOUND);\r
       }\r
       switch (Type) {\r
-        case   SCRIPT_FILE_NAME:\r
+        case   Script_File_Name:\r
           Status = RunScriptFile (CommandWithPath);\r
           break;\r
-        case   EFI_APPLICATION:\r
+        case   Efi_Application:\r
           //\r
           // Get the device path of the application image\r
           //\r
@@ -1975,10 +2076,20 @@ RunCommandOrFile(
           //\r
           // Update last error status.\r
           //\r
-          SetLastError(StatusCode);\r
+          SetLastError((SHELL_STATUS) StatusCode);\r
+          break;\r
+        default:\r
+          //\r
+          // Do nothing.\r
+          //\r
           break;\r
       }\r
       break;\r
+    default:\r
+      //\r
+      // Do nothing.\r
+      //\r
+      break;\r
   }\r
 \r
   SHELL_FREE_NON_NULL(CommandWithPath);\r
@@ -2086,7 +2197,7 @@ RunCommand(
     return (EFI_SUCCESS);\r
   }\r
 \r
-  Status = ProcessCommandLineAliasVariable(&CleanOriginal);\r
+  Status = ProcessCommandLineToFinal(&CleanOriginal);\r
   if (EFI_ERROR(Status)) {\r
     SHELL_FREE_NON_NULL(CleanOriginal);\r
     return (Status);\r
@@ -2116,12 +2227,12 @@ RunCommand(
   // Depending on the first parameter we change the behavior\r
   //\r
   switch (Type = GetOperationType(FirstParameter)) {\r
-    case   FILE_SYS_CHANGE:\r
+    case   File_Sys_Change:\r
       Status = ChangeMappedDrive(CleanOriginal);\r
       break;\r
-    case   INTERNAL_COMMAND:\r
-    case   SCRIPT_FILE_NAME:\r
-    case   EFI_APPLICATION:\r
+    case   Internal_Command:\r
+    case   Script_File_Name:\r
+    case   Efi_Application:\r
       Status = SetupAndRunCommandOrFile(Type, CleanOriginal, FirstParameter, ShellInfoObject.NewShellParametersProtocol);\r
       break;\r
     default:\r
@@ -2129,7 +2240,7 @@ RunCommand(
       // Whatever was typed, it was invalid.\r
       //\r
       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);\r
-      SetLastError(EFI_NOT_FOUND);\r
+      SetLastError(SHELL_NOT_FOUND);\r
       break;\r
   }\r
  \r