private Stream CheckSFX(Stream stream) { RewindableStream rewindableStream = GetRewindableStream(stream); stream = rewindableStream; BinaryReader reader = new BinaryReader(rewindableStream); try { int count = 0; while (true) { byte firstByte = reader.ReadByte(); if (firstByte == 0x52) { MemoryStream buffer = new MemoryStream(); byte[] nextThreeBytes = reader.ReadBytes(3); if ((nextThreeBytes[0] == 0x45) && (nextThreeBytes[1] == 0x7E) && (nextThreeBytes[2] == 0x5E)) { //old format and isvalid buffer.WriteByte(0x52); buffer.Write(nextThreeBytes, 0, 3); rewindableStream.Rewind(buffer); break; } byte[] secondThreeBytes = reader.ReadBytes(3); if ((nextThreeBytes[0] == 0x61) && (nextThreeBytes[1] == 0x72) && (nextThreeBytes[2] == 0x21) && (secondThreeBytes[0] == 0x1A) && (secondThreeBytes[1] == 0x07) && (secondThreeBytes[2] == 0x00)) { //new format and isvalid buffer.WriteByte(0x52); buffer.Write(nextThreeBytes, 0, 3); buffer.Write(secondThreeBytes, 0, 3); rewindableStream.Rewind(buffer); break; } buffer.Write(nextThreeBytes, 0, 3); buffer.Write(secondThreeBytes, 0, 3); rewindableStream.Rewind(buffer); } if (count > MAX_SFX_SIZE) { break; } } } catch (Exception e) { if (!FlagUtility.HasFlag(Options, Options.KeepStreamsOpen)) { #if NET2 || UNITY reader.Close(); #else reader.Dispose(); #endif } throw new InvalidFormatException("Error trying to read rar signature.", e); } return(stream); }
protected override void ReadFromReader(MarkingBinaryReader reader) { uint lowUncompressedSize = reader.ReadUInt32(); HostOS = (HostOS)reader.ReadByte(); FileCRC = reader.ReadUInt32(); FileLastModifiedTime = Utility.DosDateToDateTime(reader.ReadInt32()); RarVersion = reader.ReadByte(); PackingMethod = reader.ReadByte(); short nameSize = reader.ReadInt16(); FileAttributes = reader.ReadInt32(); uint highCompressedSize = 0; uint highUncompressedkSize = 0; if (FlagUtility.HasFlag(FileFlags, 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 (FlagUtility.HasFlag(FileFlags, FileFlags.UNICODE)) { int length = 0; while (length < fileNameBytes.Length && fileNameBytes[length] != 0) { length++; } if (length != nameSize) { length++; FileName = FileNameDecoder.Decode(fileNameBytes, length); } else { FileName = DecodeDefault(fileNameBytes); } } else { FileName = DecodeDefault(fileNameBytes); } FileName = ConvertPath(FileName, HostOS); } break; case HeaderType.NewSubHeader: { int datasize = HeaderSize - NEWLHD_SIZE - nameSize; if (FlagUtility.HasFlag(FileFlags, 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 (FlagUtility.HasFlag(FileFlags, FileFlags.SALT)) { Salt = reader.ReadBytes(SALT_SIZE); } if (FlagUtility.HasFlag(FileFlags, 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); } } }