]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ShellPkg/redirection: Insert \xFEFF after converting ASCII to Unicode
authorRuiyu Ni <ruiyu.ni@intel.com>
Wed, 8 Aug 2018 10:15:54 +0000 (18:15 +0800)
committerRuiyu Ni <ruiyu.ni@intel.com>
Thu, 16 Aug 2018 08:03:15 +0000 (16:03 +0800)
When "<a" is used to redirect ASCII file to an application, Shell
core reads the ASCII file and converts the ASCII to Unicode as the
input source of the application.
But per Shell spec, the input source should have \xFEFF to indicate
it's a Unicode stream.
The patch adds the missing \xFEFF.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>
ShellPkg/Application/Shell/FileHandleWrappers.c

index 8c62eb58628c26489478d4f4f72224ecf5bf85ea..655854b25dc02ef66aca80e1ec45fd8913014ac6 100644 (file)
@@ -1924,42 +1924,58 @@ FileInterfaceFileRead(
   OUT VOID                    *Buffer\r
   )\r
 {\r
   OUT VOID                    *Buffer\r
   )\r
 {\r
+  EFI_STATUS  Status;\r
+  UINT64      Position;\r
   CHAR8       *AsciiStrBuffer;\r
   CHAR16      *UscStrBuffer;\r
   UINTN       Size;\r
   CHAR8       *AsciiStrBuffer;\r
   CHAR16      *UscStrBuffer;\r
   UINTN       Size;\r
-  UINTN       CharNum;\r
-  EFI_STATUS  Status;\r
   if (((EFI_FILE_PROTOCOL_FILE*)This)->Unicode) {\r
     //\r
     // Unicode\r
   if (((EFI_FILE_PROTOCOL_FILE*)This)->Unicode) {\r
     //\r
     // Unicode\r
+    // There might be different file tag for the Unicode file. We cannot unconditionally insert the \xFEFF.\r
+    // So we choose to leave the file content as is.\r
     //\r
     return (((EFI_FILE_PROTOCOL_FILE*)This)->Orig->Read(((EFI_FILE_PROTOCOL_FILE*)This)->Orig, BufferSize, Buffer));\r
   } else {\r
     //\r
     // Ascii\r
     //\r
     //\r
     return (((EFI_FILE_PROTOCOL_FILE*)This)->Orig->Read(((EFI_FILE_PROTOCOL_FILE*)This)->Orig, BufferSize, Buffer));\r
   } else {\r
     //\r
     // Ascii\r
     //\r
-    Size  = (*BufferSize) / sizeof(CHAR16);\r
-    AsciiStrBuffer = AllocateZeroPool(Size + sizeof(CHAR8));\r
+    *BufferSize = *BufferSize / sizeof (CHAR16) * sizeof (CHAR16);\r
+    if (*BufferSize == 0) {\r
+      return EFI_SUCCESS;\r
+    }\r
+    Status = ((EFI_FILE_PROTOCOL_FILE*)This)->Orig->GetPosition (((EFI_FILE_PROTOCOL_FILE*)This)->Orig, &Position);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+    if (Position == 0) {\r
+      //\r
+      // First two bytes in Buffer is for the Unicode file tag.\r
+      //\r
+      *(CHAR16 *)Buffer = gUnicodeFileTag;\r
+      Buffer = (CHAR16 *)Buffer + 1;\r
+      Size   = *BufferSize / sizeof (CHAR16) - 1;\r
+    } else {\r
+      Size   = *BufferSize / sizeof (CHAR16);\r
+    }\r
+    AsciiStrBuffer = AllocateZeroPool (Size + 1);\r
     if (AsciiStrBuffer == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     if (AsciiStrBuffer == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
-    UscStrBuffer = AllocateZeroPool(*BufferSize + sizeof(CHAR16));\r
+    UscStrBuffer = AllocateZeroPool ((Size + 1) * sizeof(CHAR16));\r
     if (UscStrBuffer== NULL) {\r
       SHELL_FREE_NON_NULL(AsciiStrBuffer);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     if (UscStrBuffer== NULL) {\r
       SHELL_FREE_NON_NULL(AsciiStrBuffer);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
-    Status = (((EFI_FILE_PROTOCOL_FILE*)This)->Orig->Read(((EFI_FILE_PROTOCOL_FILE*)This)->Orig, &Size, AsciiStrBuffer));\r
+    Status = ((EFI_FILE_PROTOCOL_FILE*)This)->Orig->Read (((EFI_FILE_PROTOCOL_FILE*)This)->Orig, &Size, AsciiStrBuffer);\r
     if (!EFI_ERROR(Status)) {\r
     if (!EFI_ERROR(Status)) {\r
-      CharNum = UnicodeSPrint(UscStrBuffer, *BufferSize + sizeof(CHAR16), L"%a", AsciiStrBuffer);\r
-      if (CharNum == Size) {\r
-        CopyMem (Buffer, UscStrBuffer, *BufferSize);\r
-      } else {\r
-        Status = EFI_UNSUPPORTED;\r
-      }\r
+      AsciiStrToUnicodeStrS (AsciiStrBuffer, UscStrBuffer, Size + 1);\r
+      *BufferSize = Size * sizeof (CHAR16);\r
+      CopyMem (Buffer, UscStrBuffer, *BufferSize);\r
     }\r
     }\r
-    SHELL_FREE_NON_NULL(AsciiStrBuffer);\r
-    SHELL_FREE_NON_NULL(UscStrBuffer);\r
-    return (Status);\r
+    SHELL_FREE_NON_NULL (AsciiStrBuffer);\r
+    SHELL_FREE_NON_NULL (UscStrBuffer);\r
+    return Status;\r
   }\r
 }\r
 \r
   }\r
 }\r
 \r