private void CheckStamp() { // Can't read as uint32 directly since a integer format is non-encoded // in a standard format. var stamp = BitConverter.ToUInt32(vcdReader.ReadBytes(4), 0); if ((stamp & 0xFFFFFF) != MagicStamp) { throw new FormatException("not a VCDIFF input"); } if (stamp >> 24 > SupportedVersion) { throw new FormatException("VCDIFF input version > 0 is not supported"); } }
private Window ReadWindow() { var window = new Window(); // Get window indicator window.Source = (WindowFields)vcdReader.ReadByte(); if (window.Source.Contains(WindowFields.NotSupported)) { throw new FormatException("unrecognized window indicator bits set"); } if (window.Source.Contains(WindowFields.Source | WindowFields.Target)) { window.SourceSegmentLength = vcdReader.ReadInteger(); window.SourceSegmentOffset = vcdReader.ReadInteger(); } // Copy offset and copy length may not overflow if (window.SourceSegmentOffset.CheckOverflow(window.SourceSegmentLength)) { throw new FormatException("decoder copy window overflows a file offset"); } // Check copy window bounds if (window.Source.Contains(WindowFields.Target) && window.SourceSegmentOffset + window.SourceSegmentLength > lastWindowOffset) { throw new FormatException("VCD_TARGET window out of bounds"); } // Start of Delta Encoding Data vcdReader.ReadInteger(); // Length of the delta encoding (following data) // Get the length of target window window.TargetWindowLength = vcdReader.ReadInteger(); lastWindowLength = window.TargetWindowLength; // Set the maximum decoder position, beyond which we should not // decode any data. This may not exceed the size of a UInt32. if (window.SourceSegmentLength.CheckOverflow(window.TargetWindowLength)) { throw new FormatException("decoder target window overflows a UInt32"); } // Check for malicious files if (window.TargetWindowLength > HardMaxWindowSize) { throw new FormatException("Hard window size exceeded"); } // Get compressed / delta fields window.CompressedFields = (WindowCompressedFields)vcdReader.ReadByte(); if (window.CompressedFields.Contains(WindowCompressedFields.Invalid)) { throw new FormatException("unrecognized delta indicator bits set"); } // Compressed fields is only used with secondary compression if (window.CompressedFields != WindowCompressedFields.None && header.SecondaryCompressor == SecondaryCompressor.None) { throw new FormatException("invalid delta indicator bits set"); } // Read section lengths var dataLength = vcdReader.ReadInteger(); var instructionsLength = vcdReader.ReadInteger(); var addressesLength = vcdReader.ReadInteger(); // Read checksum if so (it's in big-endian-non-integer) if (window.Source.Contains(WindowFields.Adler32)) { var checksum = vcdReader.ReadBytes(4); window.Checksum = (uint)((checksum[0] << 24) | (checksum[1] << 16) | (checksum[2] << 8) | checksum[3]); } // Read sections var data = new MemoryStream(vcdReader.ReadBytes(dataLength)); var instructions = new MemoryStream(vcdReader.ReadBytes(instructionsLength)); var addresses = new MemoryStream(vcdReader.ReadBytes(addressesLength)); window.Data = new VcdReader(data); window.Instructions = new VcdReader(instructions); window.Addresses = new VcdReader(addresses); return(window); }