public void GetUncompressedLengthExceptions() { var uncompressed = Encoding.ASCII.GetBytes("Hello, hello, howdy?"); var compressed = CompressTool.Compress(uncompressed); var buffer = new byte[100]; TestException(() => { CompressTool.GetUncompressedLength(null, 0, 3); }, typeof(ArgumentNullException)); TestException(() => { CompressTool.GetUncompressedLength(compressed, -1, uncompressed.Length); }, typeof(ArgumentOutOfRangeException)); TestException(() => { CompressTool.GetUncompressedLength(compressed, 0, -1); }, typeof(ArgumentOutOfRangeException)); TestException(() => { CompressTool.GetUncompressedLength(compressed, compressed.Length - 2, 4); }, typeof(ArgumentOutOfRangeException)); TestException(() => { CompressTool.GetUncompressedLength(compressed, 0, 0); }, typeof(System.IO.IOException)); TestException(() => { CompressTool.GetUncompressedLength(compressed, compressed.Length, 0); }, typeof(System.IO.IOException)); }
/// <summary> /// Retrieves Snappy frame from underlying stream. Retrieved frame data is stored in properties of this object. /// Return value indicates end of stream. Exceptions indicate data integrity errors and underlying stream errors. /// </summary> /// <param name="stream">Underlying stream that will be read by this method.</param> /// <returns> /// True if frame was successfully retrieved. False if there are no more frames in the stream, i.e. the end of stream has been reached. /// Note that reaching the end of stream in the middle of the frame is considered an error and causes exception instead. /// </returns> public bool Read(Stream stream) { try { var headerRead = stream.Read(WordBuffer, 0, 4); if (headerRead == 0) { return(false); } EnsureRead(stream, WordBuffer, headerRead, 4 - headerRead); Type = (SnappyFrameType)WordBuffer[0]; int length = WordBuffer[1] + ((int)WordBuffer[2] << 8) + ((int)WordBuffer[3] << 16); if (Type == SnappyFrameType.Compressed || Type == SnappyFrameType.Uncompressed) { if (length < 4) { throw new InvalidDataException(); } EnsureRead(stream, WordBuffer, 0, 4); Checksum = (uint)WordBuffer[0] + ((uint)WordBuffer[1] << 8) + ((uint)WordBuffer[2] << 16) + ((uint)WordBuffer[3] << 24); BufferUsage = length - 4; if (BufferUsage > MaxBufferUsage) { throw new InvalidDataException(); } EnsureBuffer(BufferUsage); EnsureRead(stream, Buffer, 0, BufferUsage); DataLength = Type == SnappyFrameType.Uncompressed ? BufferUsage : CompressTool.GetUncompressedLength(Buffer, 0, BufferUsage); if (DataLength > MaxFrameSize) { throw new InvalidDataException(); } } else if (Type == SnappyFrameType.Padding || (byte)Type >= (byte)SnappyFrameType.SkippableFirst && (byte)Type <= (byte)SnappyFrameType.SkippableLast) { DataLength = length; BufferUsage = 0; Checksum = 0; SkipBytes(stream, length); } else if (Type == SnappyFrameType.StreamIdentifier) { if (length != 6) { throw new InvalidOperationException(); } DataLength = 6; BufferUsage = 0; Checksum = 0; EnsureBuffer(6); EnsureRead(stream, Buffer, 0, 6); if (!Utils.BuffersEqual(Buffer, StreamIdentifier, 6)) { throw new InvalidDataException(); } } else { throw new InvalidDataException(); } return(true); } catch { SetPadding(0); throw; } }