Variant Records Unsafe in .Net

It turns out that variant records, that is records with overlapping fields, are considered unsafe by the .Net CLR. A pity, since I use these things all the time to crack message buffers and the like. Fortunately, what .Net takes away, new features of the Delphi language give back. Because it is now possible to have methods and properties attached to records it is fairly easy to simulate variant records.

In the Essentials component I cam across the following record description:

TRGBMap = packed record
case Byte of
0 : (RGBValue : DWord);
1 : (Red : Byte;
Green : Byte;
Blue : Byte;
Unused : Byte);
end;

A nice, simple record to crack the Red, Green and Blue values out of a TColor value. Unfortunately, not considered safe by .Net. Fortunately, the fix is quite easy. By using the advanced features of Delphi’s record type it is easy to create an equivalent record that is transparent to the code that uses it.

Simply create a record that has a single field named RGBValue, then create properties for Red, Green and Blue. Like this:

TRGBMap = record
var
RGBValue : DWORD;
private
function GetBlue: Byte;
function GetGreen: Byte;
function GetRed: Byte;
procedure SetBlue(const Value: Byte);
procedure SetGreen(const Value: Byte);
procedure SetRed(const Value: Byte);
public
property Red: Byte read GetRed write SetRed;
property Blue: Byte read GetBlue write SetBlue;
property Green: Byte read GetGreen write SetGreen;
end;
function TRGBMap.GetBlue: Byte;
begin
Result := (RGBValue and $00FF0000) shr 16;
end;

function TRGBMap.GetGreen: Byte;
begin
Result := (RGBValue and $0000FF00) shr 8;
end;

function TRGBMap.GetRed: Byte;
begin
Result := RGBValue and $000000FF;
end;

procedure TRGBMap.SetBlue(const Value: Byte);
begin
RGBValue := (RGBValue and $FF00FFFF) or (Value shl 16);
end;

procedure TRGBMap.SetGreen(const Value: Byte);
begin
RGBValue := (RGBValue and $FFFF00FF) or (Value shl 8);
end;

procedure TRGBMap.SetRed(const Value: Byte);
begin
RGBValue := (RGBValue and $FFFFFF00) or Value;
end;

Leave a Reply