예제 #1
0
        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");
            }
        }
예제 #2
0
        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);
        }