]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellLevel3CommandsLib/Type.c
ShellPkg/for: Fix potential null pointer deference
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel3CommandsLib / Type.c
index 05f13f07565da2ec9f4eaa7f11a69399645d47be..50d18e45aacd80ac1cceb57ca468df9882bec13d 100644 (file)
@@ -1,7 +1,8 @@
 /** @file\r
   Main file for Type shell level 3 function.\r
 \r
-  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved. <BR>\r
+  (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>\r
+  Copyright (c) 2009 - 2011, 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
 \r
 #include <Library/ShellLib.h>\r
 \r
+/**\r
+  Display a single file to StdOut.\r
+\r
+  If both Ascii and UCS2 are FALSE attempt to discover the file type.\r
+\r
+  @param[in] Handle   The handle to the file to display.\r
+  @param[in] Ascii    TRUE to force ASCII, FALSE othewise.\r
+  @param[in] UCS2     TRUE to force UCS2, FALSE othewise.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.\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 = PcdGet16(PcdShellFileOperationSize);\r
-  Buffer = AllocatePool(ReadSize);\r
-  if (Buffer == NULL) {\r
+  ReadSize = PcdGet32(PcdShellFileOperationSize);\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)PcdGet16(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 (*(UINT16*)Buffer == UnicodeFileTag) {\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
-  Status = Print(L"\r\n", Buffer);\r
+  FreePool (AllocatedBuffer);\r
+  ShellPrintEx (-1, -1, L"\r\n");\r
   return (Status);\r
 }\r
 \r
@@ -125,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
@@ -142,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
@@ -161,6 +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, L"type", (CHAR16*)Param);  \r
           ShellStatus = SHELL_NOT_FOUND;\r
           break;\r
         }\r
@@ -173,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
@@ -183,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
@@ -196,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
@@ -204,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