ShellPkg/redirection: Insert \xFEFF after converting ASCII to Unicode

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>
This commit is contained in:
Ruiyu Ni 2018-08-08 18:15:54 +08:00
parent 7b85a1afa3
commit bc0d3e2912
1 changed files with 31 additions and 15 deletions

View File

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