Skip to content

Commit

Permalink
Big-endian fix: Accessing OBJECTHEADER in ImageConverter (#50499)
Browse files Browse the repository at this point in the history
* Big-endian fix: Accessing OBJECTHEADER in ImageConverter

The GetBitmapStream routine in ImageConverter is supposed to
skip an embedded OBJECTHEADER structure.  However, this
structure needs to be read in little-endian mode, not in
native byte order.

Fixes the ImageConverterTest.ImageWithOleHeader test on
big-endian systems.

* Update src/libraries/System.Drawing.Common/src/System/Drawing/ImageConverter.cs

Co-authored-by: Stephen Toub <[email protected]>
  • Loading branch information
uweigand and stephentoub authored Apr 1, 2021
1 parent e5efbd8 commit 78acffe
Showing 1 changed file with 24 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Buffers.Binary;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing.Imaging;
Expand Down Expand Up @@ -112,20 +113,38 @@ public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContex
{
try
{
short signature = MemoryMarshal.Read<short>(rawData);
short signature = BinaryPrimitives.ReadInt16LittleEndian(rawData);

if (signature != 0x1c15)
{
return null;
}

// The data is in the form of OBJECTHEADER. It's an encoded format that Access uses to push imagesinto the DB.
OBJECTHEADER pHeader = MemoryMarshal.Read<OBJECTHEADER>(rawData);
// The data is in the form of OBJECTHEADER. It's an encoded format that Access uses to push images into the DB.
//
// The layout of OBJECTHEADER is as follows - we only need the signature
// and headersize fields, which need to be read as little-endian data:
//
// [StructLayout(LayoutKind.Sequential)]
// private struct OBJECTHEADER
// {
// public short signature; // it's always 0x1c15
// public short headersize;
// public short objectType;
// public short nameLen;
// public short classLen;
// public short nameOffset;
// public short classOffset;
// public short width;
// public short height;
// public IntPtr pInfo;
// }
short headersize = BinaryPrimitives.ReadInt16LittleEndian(rawData.Slice(2, 2));

// pHeader.signature will always be 0x1c15.
// "PBrush" should be the 6 chars after position 12 as well.
if (rawData.Length <= pHeader.headersize + 18 ||
!rawData.Slice(pHeader.headersize + 12, 6).SequenceEqual(PBrush))
if (rawData.Length <= headersize + 18 ||
!rawData.Slice(headersize + 12, 6).SequenceEqual(PBrush))
{
return null;
}
Expand All @@ -143,20 +162,5 @@ public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContex

return null;
}

[StructLayout(LayoutKind.Sequential)]
private struct OBJECTHEADER
{
public short signature; // it's always 0x1c15
public short headersize;
public short objectType;
public short nameLen;
public short classLen;
public short nameOffset;
public short classOffset;
public short width;
public short height;
public IntPtr pInfo;
}
}
}

0 comments on commit 78acffe

Please sign in to comment.