]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellLevel3CommandsLib/Type.c
ShellPkg/DP: Add more check for input parameters
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel3CommandsLib / Type.c
index 50974c3fb9499534ba2d100a70bcd525e934fd47..854c25a103e309f1915b9a128c6cc083a1b46022 100644 (file)
@@ -1,7 +1,8 @@
 /** @file\r
   Main file for Type shell level 3 function.\r
 \r
-  Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved. <BR>\r
+  (C) Copyright 2013-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
   @retval EFI_SUCCESS           The operation was successful.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 TypeFileByHandle (\r
-  IN EFI_HANDLE Handle,\r
-  BOOLEAN Ascii,\r
-  BOOLEAN UCS2\r
+  IN SHELL_FILE_HANDLE Handle,\r
+  IN BOOLEAN Ascii,\r
+  IN BOOLEAN UCS2\r
   )\r
 {\r
   UINTN       ReadSize;\r
   VOID        *Buffer;\r
+  VOID        *AllocatedBuffer;\r
   EFI_STATUS  Status;\r
   UINTN       LoopVar;\r
+  UINTN       LoopSize;\r
   CHAR16      AsciiChar;\r
+  CHAR16      Ucs2Char;\r
 \r
   ReadSize = PcdGet32(PcdShellFileOperationSize);\r
-  Buffer = AllocateZeroPool(ReadSize);\r
-  if (Buffer == NULL) {\r
+  AllocatedBuffer = AllocateZeroPool(ReadSize);\r
+  if (AllocatedBuffer == NULL) {\r
     return (EFI_OUT_OF_RESOURCES);\r
   }\r
 \r
   Status = ShellSetFilePosition(Handle, 0);\r
   ASSERT_EFI_ERROR(Status);\r
 \r
-  while (ReadSize == ((UINTN)PcdGet32(PcdShellFileOperationSize))){\r
+  while (ReadSize == ((UINTN)PcdGet32(PcdShellFileOperationSize))) {\r
+    Buffer = AllocatedBuffer;\r
     ZeroMem(Buffer, ReadSize);\r
     Status = ShellReadFile(Handle, &ReadSize, Buffer);\r
     if (EFI_ERROR(Status)){\r
       break;\r
     }\r
 \r
-    if (!(Ascii|UCS2)){\r
+    if (!(Ascii|UCS2)) {\r
       if (*(UINT16*)Buffer == gUnicodeFileTag) {\r
         UCS2 = TRUE;\r
-        Buffer = ((UINT16*)Buffer) + 1;\r
       } else {\r
         Ascii = TRUE;\r
       }\r
     }\r
 \r
-    //\r
-    // We want to use plain Print function here! (no color support for files)\r
-    //\r
-    if (Ascii){\r
-      for (LoopVar = 0 ; LoopVar < ReadSize ; LoopVar++) {\r
-      AsciiChar = CHAR_NULL;\r
-      AsciiChar = ((CHAR8*)Buffer)[LoopVar];\r
-      if (AsciiChar == CHAR_NULL) {\r
-        AsciiChar = '.';\r
-      }\r
-      Print(L"%c", AsciiChar);\r
+    if (Ascii) {\r
+      LoopSize = ReadSize;\r
+      for (LoopVar = 0 ; LoopVar < LoopSize ; LoopVar++) {\r
+        //\r
+        // The valid range of ASCII characters is 0x20-0x7E.\r
+        // Display "." when there is an invalid character.\r
+        //\r
+        AsciiChar = CHAR_NULL;\r
+        AsciiChar = ((CHAR8*)Buffer)[LoopVar];\r
+        if (AsciiChar == '\r' || AsciiChar == '\n') {\r
+          //\r
+          // Allow Line Feed (LF) (0xA) & Carriage Return (CR) (0xD)\r
+          // characters to be displayed as is.\r
+          //\r
+          if (AsciiChar == '\n' && ((CHAR8*)Buffer)[LoopVar-1] != '\r') {\r
+            //\r
+            // In case Line Feed (0xA) is encountered & Carriage Return (0xD)\r
+            // was not the previous character, print CR and LF. This is because\r
+            // Shell 2.0 requires carriage return with line feed for displaying\r
+            // each new line from left.\r
+            //\r
+            ShellPrintEx (-1, -1, L"\r\n");\r
+            continue;\r
+          }\r
+        } else {\r
+          //\r
+          // For all other characters which are not printable, display '.'\r
+          //\r
+          if (AsciiChar < 0x20 || AsciiChar >= 0x7F) {\r
+            AsciiChar = '.';\r
+          }\r
+        }\r
+        ShellPrintEx (-1, -1, L"%c", AsciiChar);\r
       }\r
     } else {\r
-      Print(L"%s", Buffer);\r
+      if (*(UINT16*)Buffer == gUnicodeFileTag) {\r
+        //\r
+        // For unicode files, skip displaying the byte order marker.\r
+        //\r
+        Buffer = ((UINT16*)Buffer) + 1;\r
+        LoopSize = (ReadSize / (sizeof (CHAR16))) - 1;\r
+      } else {\r
+        LoopSize = ReadSize / (sizeof (CHAR16));\r
+      }\r
+\r
+      for (LoopVar = 0 ; LoopVar < LoopSize ; LoopVar++) {\r
+        //\r
+        // An invalid range of characters is 0x0-0x1F.\r
+        // Display "." when there is an invalid character.\r
+        //\r
+        Ucs2Char = CHAR_NULL;\r
+        Ucs2Char = ((CHAR16*)Buffer)[LoopVar];\r
+        if (Ucs2Char == '\r' || Ucs2Char == '\n') {\r
+          //\r
+          // Allow Line Feed (LF) (0xA) & Carriage Return (CR) (0xD)\r
+          // characters to be displayed as is.\r
+          //\r
+          if (Ucs2Char == '\n' && ((CHAR16*)Buffer)[LoopVar-1] != '\r') {\r
+            //\r
+            // In case Line Feed (0xA) is encountered & Carriage Return (0xD)\r
+            // was not the previous character, print CR and LF. This is because\r
+            // Shell 2.0 requires carriage return with line feed for displaying\r
+            // each new line from left.\r
+            //\r
+            ShellPrintEx (-1, -1, L"\r\n");\r
+            continue;\r
+          }\r
+        }\r
+        else if (Ucs2Char < 0x20) {\r
+          //\r
+          // For all other characters which are not printable, display '.'\r
+          //\r
+          Ucs2Char = L'.';\r
+        }\r
+        ShellPrintEx (-1, -1, L"%c", Ucs2Char);\r
+      }\r
+    }\r
+\r
+    if (ShellGetExecutionBreakFlag()) {\r
+      break;\r
     }\r
   }\r
-  Print(L"\r\n", Buffer);\r
+  FreePool (AllocatedBuffer);\r
+  ShellPrintEx (-1, -1, L"\r\n");\r
   return (Status);\r
 }\r
 \r
@@ -137,7 +207,7 @@ ShellCommandRunType (
   Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
   if (EFI_ERROR(Status)) {\r
     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel3HiiHandle, ProblemParam);\r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel3HiiHandle, L"type", ProblemParam);\r
       FreePool(ProblemParam);\r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
     } else {\r
@@ -154,13 +224,13 @@ ShellCommandRunType (
     UnicodeMode = ShellCommandLineGetFlag(Package, L"-u");\r
 \r
     if (AsciiMode && UnicodeMode) {\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel3HiiHandle, L"-a & -u");\r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel3HiiHandle, L"type", L"-a & -u");\r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
    } else if (ShellCommandLineGetRawValue(Package, 1) == NULL) {\r
       //\r
       // we insufficient parameters\r
       //\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel3HiiHandle);\r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel3HiiHandle, L"type");\r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
     } else {\r
       //\r
@@ -173,7 +243,7 @@ ShellCommandRunType (
          ){\r
         Status = ShellOpenFileMetaArg((CHAR16*)Param, EFI_FILE_MODE_READ, &FileList);\r
         if (EFI_ERROR(Status)) {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel3HiiHandle, (CHAR16*)Param);\r
+          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel3HiiHandle, L"type", (CHAR16*)Param);\r
           ShellStatus = SHELL_NOT_FOUND;\r
           break;\r
         }\r
@@ -186,7 +256,7 @@ ShellCommandRunType (
           // check that we have at least 1 file\r
           //\r
           if (FileList == NULL || IsListEmpty(&FileList->Link)) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel3HiiHandle, Param);\r
+            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel3HiiHandle, L"type", Param);\r
             continue;\r
           } else {\r
             //\r
@@ -196,11 +266,16 @@ ShellCommandRunType (
                 ; !IsNull(&FileList->Link, &Node->Link) && !ShellGetExecutionBreakFlag()\r
                 ; Node = (EFI_SHELL_FILE_INFO*)GetNextNode(&FileList->Link, &Node->Link)\r
                ){\r
+\r
+              if (ShellGetExecutionBreakFlag()) {\r
+                break;\r
+              }\r
+\r
               //\r
               // make sure the file opened ok\r
               //\r
               if (EFI_ERROR(Node->Status)){\r
-                ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NO_OPEN), gShellLevel3HiiHandle, Node->FileName, Node->Status);\r
+                ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel3HiiHandle, L"type", Node->FileName);\r
                 ShellStatus = SHELL_NOT_FOUND;\r
                 continue;\r
               }\r
@@ -209,7 +284,7 @@ ShellCommandRunType (
               // make sure its not a directory\r
               //\r
               if (FileHandleIsDirectory(Node->Handle) == EFI_SUCCESS) {\r
-                ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_IS_DIR), gShellLevel3HiiHandle, Node->FileName);\r
+                ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_IS_DIR), gShellLevel3HiiHandle, L"type", Node->FileName);\r
                 ShellStatus = SHELL_NOT_FOUND;\r
                 continue;\r
               }\r
@@ -217,9 +292,9 @@ ShellCommandRunType (
               //\r
               // do it\r
               //\r
-              Status = TypeFileByHandle(Node->Handle, AsciiMode, UnicodeMode);\r
+              Status = TypeFileByHandle (Node->Handle, AsciiMode, UnicodeMode);\r
               if (EFI_ERROR(Status)) {\r
-                ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TYP_ERROR), gShellLevel3HiiHandle, Node->FileName, Status);\r
+                ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TYP_ERROR), gShellLevel3HiiHandle, L"type", Node->FileName);\r
                 ShellStatus = SHELL_INVALID_PARAMETER;\r
               }\r
               ASSERT(ShellStatus == SHELL_SUCCESS);\r