public void TestDecoderReturnsValidData()
        {
            IFilenameDecoder testSubject = new FileNameDecoder();

            foreach (Expectation expectation in decoderDataProvider())
            {
                DecodedFileName decodedFileName = testSubject.DecodeFilename(expectation.TestFilename);
                Assert.AreEqual(expectation.HeaderType, decodedFileName.HeaderType);
                for (int i = 0; i < expectation.HeaderData.Length; i++)
                {
                    Assert.AreEqual(expectation.HeaderData[i], decodedFileName.HeaderData[i]);
                }
                Assert.AreEqual(expectation.Filename, decodedFileName.Filename);
            }
        }
Exemple #2
0
        protected override void ReadFromReader(MarkingBinaryReader reader)
        {
            FileHeaderFlags = (FileFlags)reader.ReadVInt();
            UnpackedSize    = reader.ReadVInt();
            Attributes      = reader.ReadVInt();
            if (FileHeaderFlags.HasFlag(FileFlags.TimeFieldIsPresent))
            {
                MTime = reader.ReadUInt32();
                FileLastModifiedTime = Utility.UnixTimeToDateTime(MTime);
            }
            if (FileHeaderFlags.HasFlag(FileFlags.CRC32IsPresent))
            {
                DataCRC32 = reader.ReadUInt32();
            }
            CompressionInformation = reader.ReadVInt();
            HostOS = (HostOS)reader.ReadVInt();

            var nameSize = (int)reader.ReadVInt();

            Name = Encoding.UTF8.GetString(reader.ReadBytes(nameSize));

            uint highCompressedSize    = 0;
            uint highUncompressedkSize = 0;

            if (FileFlags.HasFlag(FileFlags.LARGE))
            {
                highCompressedSize    = reader.ReadUInt32();
                highUncompressedkSize = reader.ReadUInt32();
            }
            else
            {
                if (lowUncompressedSize == 0xffffffff)
                {
                    lowUncompressedSize   = 0xffffffff;
                    highUncompressedkSize = int.MaxValue;
                }
            }
            CompressedSize   = UInt32To64(highCompressedSize, AdditionalSize);
            UncompressedSize = UInt32To64(highUncompressedkSize, lowUncompressedSize);

            nameSize = nameSize > 4 * 1024 ? (short)(4 * 1024) : nameSize;

            byte[] fileNameBytes = reader.ReadBytes(nameSize);

            switch (HeaderType)
            {
            case HeaderType.FileHeader:
            {
                if (FileFlags.HasFlag(FileFlags.UNICODE))
                {
                    int length = 0;
                    while (length < fileNameBytes.Length &&
                           fileNameBytes[length] != 0)
                    {
                        length++;
                    }
                    if (length != nameSize)
                    {
                        length++;
                        FileName = FileNameDecoder.Decode(fileNameBytes, length);
                    }
                    else
                    {
                        FileName = ArchiveEncoding.Decode(fileNameBytes);
                    }
                }
                else
                {
                    FileName = ArchiveEncoding.Decode(fileNameBytes);
                }
                FileName = ConvertPath(FileName, HostOS);
            }
            break;

            case HeaderType.NewSubHeader:
            {
                int datasize = HeaderSize - NEWLHD_SIZE - nameSize;
                if (FileFlags.HasFlag(FileFlags.SALT))
                {
                    datasize -= SALT_SIZE;
                }
                if (datasize > 0)
                {
                    SubData = reader.ReadBytes(datasize);
                }

                if (NewSubHeaderType.SUBHEAD_TYPE_RR.Equals(fileNameBytes))
                {
                    RecoverySectors = SubData[8] + (SubData[9] << 8)
                                      + (SubData[10] << 16) + (SubData[11] << 24);
                }
            }
            break;
            }

            if (FileFlags.HasFlag(FileFlags.SALT))
            {
                Salt = reader.ReadBytes(SALT_SIZE);
            }
            if (FileFlags.HasFlag(FileFlags.EXTTIME))
            {
                // verify that the end of the header hasn't been reached before reading the Extended Time.
                //  some tools incorrectly omit Extended Time despite specifying FileFlags.EXTTIME, which most parsers tolerate.
                if (ReadBytes + reader.CurrentReadByteCount <= HeaderSize - 2)
                {
                    ushort extendedFlags = reader.ReadUInt16();
                    FileLastModifiedTime = ProcessExtendedTime(extendedFlags, FileLastModifiedTime, reader, 0);
                    FileCreatedTime      = ProcessExtendedTime(extendedFlags, null, reader, 1);
                    FileLastAccessedTime = ProcessExtendedTime(extendedFlags, null, reader, 2);
                    FileArchivedTime     = ProcessExtendedTime(extendedFlags, null, reader, 3);
                }
            }
        }