Menu

#18 ReadInt64 does not work on sizes larger than int32

v2.0
closed-fixed
Federico
StreamRW (1)
5
2015-09-18
2014-12-01
Josh M
No

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);
    }

Discussion

  • Josh M

    Josh M - 2014-12-01

    I need to correct the ticket name, it should say "ReadInt64 does not work on sizes larger than uint32"

     
  • Josh M

    Josh M - 2014-12-01

    I created a patch file, see attachment.

     
  • Federico

    Federico - 2014-12-07
    • labels: --> StreamRW
    • status: open --> accepted
    • assigned_to: Federico
    • Group: v1.5 --> v2.0
     
  • Federico

    Federico - 2014-12-07

    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

     
  • Federico

    Federico - 2015-09-18
    • status: accepted --> closed-fixed
     

Log in to post a comment.

MongoDB Logo MongoDB