]> 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 3e4ccb36e34c7cae73984e3e204e846267e13c68..50d18e45aacd80ac1cceb57ca468df9882bec13d 100644 (file)
@@ -1,6 +1,7 @@
 /** @file\r
   Main file for Type shell level 3 function.\r
 \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
   @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 = AllocateZeroPool(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 (!(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