Skip to content

PEReader - Big Endian issues when getting a string #44805

@nealef

Description

@nealef

When using FileVersionInfo.GetVersionInfo the PEReader uses the standard code path for creating a string from an array of bytes that takes it to System.Text.ASCIIUtility:GetIndexOfFirstNonAsciiByte_Default which assumes the byte ordering is in the native order. However, PE objects such as, for example, Microsoft.Build.dll the strings are in little endian order (for example, the © is 0xa9c2 in the PE object but is 0xc2a9 when used on Big Endian systems). This leads to System.Text.ASCIIUtility:WidenAsciiToUtf16 returning a non-zero result and then eventually, to:

[ERROR] FATAL UNHANDLED EXCEPTION: System.ArgumentException: The output char buffer is too small to contain the decoded characters, encoding 'Unicode (UTF-8)' fallback 'System.Text.DecoderReplacementFallback'. (Parameter 'chars')
   at System.Text.Encoding.ThrowCharsOverflow(DecoderNLS decoder, Boolean nothingDecoded) in /home/neale/runtimelab/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs:line 1179
   at System.Text.Encoding.GetCharsWithFallback(ReadOnlySpan`1 bytes, Int32 originalBytesLength, Span`1 chars, Int32 originalCharsLength, DecoderNLS decoder) in /home/neale/runtimelab/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.Internal.cs:line 1272
   at System.Text.UTF8Encoding.GetCharsWithFallback(ReadOnlySpan`1 bytes, Int32 originalBytesLength, Span`1 chars, Int32 originalCharsLength, DecoderNLS decoder) in /home/neale/runtimelab/src/libraries/System.Private.CoreLib/src/System/Text/UTF8Encoding.cs:line 647
   at System.Text.Encoding.GetCharsWithFallback(Byte* pOriginalBytes, Int32 originalByteCount, Char* pOriginalChars, Int32 originalCharCount, Int32 bytesConsumedSoFar, Int32 charsWrittenSoFar) in /home/neale/runtimelab/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.Internal.cs:line 1086
   at System.Text.UTF8Encoding.GetChars(Byte* bytes, Int32 byteCount, Char* chars, Int32 charCount) in /home/neale/runtimelab/src/libraries/System.Private.CoreLib/src/System/Text/UTF8Encoding.cs:line 553
   at System.String.CreateStringFromEncoding(Byte* bytes, Int32 byteLength, Encoding encoding) in /home/neale/runtimelab/src/libraries/System.Private.CoreLib/src/System/String.cs:line 540
   at System.Text.Encoding.GetString(Byte* bytes, Int32 byteCount) in /home/neale/runtimelab/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs:line 941
   at System.Reflection.Internal.MemoryBlock.PeekUtf8(Int32 offset, Int32 byteCount) in /home/neale/runtimelab/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/MemoryBlock.cs:line 289
   at System.Reflection.Metadata.BlobReader.ReadUTF8(Int32 byteCount) in /home/neale/runtimelab/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobReader.cs:line 441
   at System.Reflection.Metadata.BlobReader.ReadSerializedString() in /home/neale/runtimelab/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobReader.cs:line 641
   at System.Diagnostics.FileVersionInfo.GetStringAttributeArgumentValue(MetadataReader reader, CustomAttribute attr, String& value) in /home/neale/runtimelab/src/libraries/System.Diagnostics.FileVersionInfo/src/System/Diagnostics/FileVersionInfo.Unix.cs:line 315
   at System.Diagnostics.FileVersionInfo.LoadManagedAssemblyMetadata(MetadataReader metadataReader, Boolean isExe) in /home/neale/runtimelab/src/libraries/System.Diagnostics.FileVersionInfo/src/System/Diagnostics/FileVersionInfo.Unix.cs:line 134
   at System.Diagnostics.FileVersionInfo.TryLoadManagedAssemblyMetadata() in /home/neale/runtimelab/src/libraries/System.Diagnostics.FileVersionInfo/src/System/Diagnostics/FileVersionInfo.Unix.cs:line 60
   at System.Diagnostics.FileVersionInfo..ctor(String fileName) in /home/neale/runtimelab/src/libraries/System.Diagnostics.FileVersionInfo/src/System/Diagnostics/FileVersionInfo.Unix.cs:line 26
   at System.Diagnostics.FileVersionInfo.GetVersionInfo(String fileName) in /home/neale/runtimelab/src/libraries/System.Diagnostics.FileVersionInfo/src/System/Diagnostics/FileVersionInfo.cs:line 279
   at HelloWorld.Program.Main(String[] args) in /home/neale/HelloWorld/Program.cs:line 14

The PE decoding takes place in BlobReader and most of the decoding is endian aware. This does not seem to be the case for ReadUTF8. It would seem that ReadUTF8 may need to scan the UTF8 and reorder the multibyte characters before converting to a string.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions