ReadInt64 does not work on sizes larger than int32
Structured Storage .net component - pure C#
Brought to you by:
ironfede
The ReadInt64 method in StreamRW does not correctly read large numbers. I found this bug while researching the other file size bug related to older OLE file formats. Below is my code change proposal that has been tested.
public long ReadInt64()
{
this.stream.Read(buffer, 0, 8);
uint ls = (uint)(buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24));
long ms = (uint)((buffer[4]) | (buffer[5] << 8) | (buffer[6] << 16) | (buffer[7] << 24)); // changed uint to long
//uint ms = (uint)( ( buffer[4] ) | ( buffer[5] << 8 ) | ( buffer[6] << 16 ) | ( buffer[7] << 24 ) );
return (ms << 32) | ls; // Fixed shifting, cast wasn't working
//return (long)((ms << 32) | ls);
}
And here are some unit tests:
[TestMethod]
public void ReadInt64_MaxSizeRead()
{
Int64 input = Int64.MaxValue;
byte[] bytes = BitConverter.GetBytes(input);
long actual = 0;
using( MemoryStream memStream = new MemoryStream( bytes ) )
{
OpenMcdf.StreamRW reader = new OpenMcdf.StreamRW(memStream);
actual = reader.ReadInt64();
}
Assert.AreEqual((long)input, actual);
}
[TestMethod]
public void ReadInt64_SmallNumber()
{
Int64 input = 1234;
byte[] bytes = BitConverter.GetBytes(input);
long actual = 0;
using (MemoryStream memStream = new MemoryStream(bytes))
{
OpenMcdf.StreamRW reader = new OpenMcdf.StreamRW(memStream);
actual = reader.ReadInt64();
}
Assert.AreEqual((long)input, actual);
}
[TestMethod]
public void ReadInt64_Int32MaxPlusTen()
{
Int64 input = (Int64)Int32.MaxValue + 10;
byte[] bytes = BitConverter.GetBytes(input);
long actual = 0;
using (MemoryStream memStream = new MemoryStream(bytes))
{
OpenMcdf.StreamRW reader = new OpenMcdf.StreamRW(memStream);
actual = reader.ReadInt64();
}
Assert.AreEqual((long)input, actual);
}
I need to correct the ticket name, it should say "ReadInt64 does not work on sizes larger than uint32"
I created a patch file, see attachment.
Many thanks for your advices on this issue. I've already integrated unit test in 2.0 (dev) branch with a fix slightly different from the correct one you suggested just to avoid mixing signed with unsigned integers.
Thank you,
Best Regards
Federico