ForeverZer0 / SharpNBT

A pure CLS-compliant C# implementation of the Named Binary Tag (NBT) format specification commonly used with Minecraft applications, allowing easy reading/writing streams and serialization to other formats.
MIT License
25 stars 9 forks source link

BaseStream.Read reads less bytes than expected due to breaking change in .NET 6 #3

Closed Arcus92 closed 2 years ago

Arcus92 commented 2 years ago

There was a breaking change in .NET 6 in DeflateStream and GZipStream. These streams can now read less bytes than requested by the Read methods count parameter. You now have to call the Read method multiple times until your buffer is filled or 0 is returned (end of base stream).

In TagReader there are a few instances where BaseStream.Read is used but the return value is ignored. For example: When reading Minecraft chunk files the NBT data is compressed by GZipStream or ZLibStream (uses DeflateStream). Chunk files can contain really long LongArrayTags that are read in a single Read call. Due to the .NET 6 change it is possible that not all bytes are read in a single call. This will mess up the read data, the stream position and the Crc in ZLibStream that will throw an InvalidDataException.

If required I can upload a region file and an example code to reproduce the problem.

Possible solutions: Create an extension method e.g. ReadFixedLength with the same signature as Stream.Read but without return value. This will call Stream.Read in a loop until all count bytes are read. This should throw an EndOfStreamException if it couldn't read the required number of bytes from the base steam.