private static void HandleUnexpectedDataDescriptor(ZipEntry entry) { // no seek - stream integrity should be protected by the caller Stream s = entry.ArchiveStream; if (ZipSharedUtilities.ReadInt(s) == entry._Crc32) { if (ZipSharedUtilities.ReadInt(s) == entry._CompressedSize) { if (ZipSharedUtilities.ReadInt(s) != entry._UncompressedSize) { s.Seek(-12L, SeekOrigin.Current); } } else { s.Seek(-8L, SeekOrigin.Current); } } else { s.Seek(-4L, SeekOrigin.Current); } }
private void InsureUniqueEntry(ZipEntry ze1) { var normalizedName = ZipSharedUtilities.TrimVolumeAndSwapSlashes(ze1.FileName); if (_entriesIndex.ContainsKey(normalizedName)) { throw new ArgumentException(String.Format("The entry '{0}' already exists in the zip archive.", ze1.FileName)); } }
private static void ReadCentralDirectoryFooter(ZipFile zf) { // no seek - stream integrity should be protected by the caller Stream s = zf.ReadStream; int signature = ZipSharedUtilities.ReadSignature(s); if (signature != 0x6054b50L) { s.Seek(-4L, SeekOrigin.Current); throw new BadReadException(String.Format(" ZipFile::Read(): Bad signature ({0:X8}) at position 0x{1:X8}", signature, s.Position)); } byte[] block = new byte[0x10]; zf.ReadStream.Read(block, 0, block.Length); ReadZipFileComment(zf); }
internal static String NameInArchive(String filename, String directoryPathInArchive) { String result = null; if (directoryPathInArchive == null) { result = filename; } else if (String.IsNullOrEmpty(directoryPathInArchive)) { result = Path.GetFileName(filename); } else { result = Path.Combine(directoryPathInArchive, Path.GetFileName(filename)); } return(ZipSharedUtilities.TrimVolumeAndSwapSlashes(result)); }
private static void ReadZipFileComment(ZipFile zf) { // no seek - stream integrity should be protected by the caller byte[] block = new byte[2]; zf.ReadStream.Read(block, 0, block.Length); short commentLength = (short)(block[0] + (block[1] * 0x100)); if (commentLength > 0) { block = new byte[commentLength]; zf.ReadStream.Read(block, 0, block.Length); if (ZipSharedUtilities.HighBytes(block) && (zf._encoding == Encoding.GetEncoding("ibm437"))) { zf._encoding = Encoding.UTF8; } zf.Comment = ZipSharedUtilities.StringFromBuffer(block, block.Length, zf._encoding); } }
private void WriteHeader(Stream s, int cycle) { byte[] bytes = new byte[0x2200]; int i = 0; bytes[i++] = 80; bytes[i++] = 0x4b; bytes[i++] = 3; bytes[i++] = 4; short VersionNeededToExctract = 20; bytes[i++] = (byte)(VersionNeededToExctract & 0xff); bytes[i++] = (byte)((VersionNeededToExctract & 0xff00) >> 8); byte[] FileNameBytes = this.GetFileNameBytes(); short filenameLength = (short)FileNameBytes.Length; this._CommentBytes = null; if (!String.IsNullOrEmpty(this._Comment)) { this._CommentBytes = this._Comment.ToByteArray(this._encoding); } bool setUtf8Bit = this.UseUtf8Encoding && (ZipSharedUtilities.HighBytes(this._CommentBytes) || ZipSharedUtilities.HighBytes(FileNameBytes)); this._BitField = ((short)0); if (setUtf8Bit) { this._BitField = (short)(this._BitField | 0x800); } if (!s.CanSeek) { this._BitField = (short)(this._BitField | 8); } bytes[i++] = (byte)(this._BitField & 0xff); bytes[i++] = (byte)((this._BitField & 0xff00) >> 8); if (this.__FileDataPosition == 0L) { this._UncompressedSize = 0; this._CompressedSize = 0; this._Crc32 = 0; } this.FigureCompressionMethodForWriting(cycle); bytes[i++] = (byte)(this.CompressionMethod & 0xff); bytes[i++] = (byte)((this.CompressionMethod & 0xff00) >> 8); this._TimeBlob = ZipSharedUtilities.DateTimeToPacked(this.LastModified); bytes[i++] = (byte)(this._TimeBlob & 0xff); bytes[i++] = (byte)((this._TimeBlob & 0xff00) >> 8); bytes[i++] = (byte)((this._TimeBlob & 0xff0000) >> 0x10); bytes[i++] = (byte)((this._TimeBlob & 0xff000000L) >> 0x18); bytes[i++] = (byte)(this._Crc32 & 0xff); bytes[i++] = (byte)((this._Crc32 & 0xff00) >> 8); bytes[i++] = (byte)((this._Crc32 & 0xff0000) >> 0x10); bytes[i++] = (byte)((this._Crc32 & 0xff000000L) >> 0x18); bytes[i++] = (byte)(this._CompressedSize & 0xff); bytes[i++] = (byte)((this._CompressedSize & 0xff00) >> 8); bytes[i++] = (byte)((this._CompressedSize & 0xff0000) >> 0x10); bytes[i++] = (byte)((this._CompressedSize & 0xff000000L) >> 0x18); bytes[i++] = (byte)(this._UncompressedSize & 0xff); bytes[i++] = (byte)((this._UncompressedSize & 0xff00) >> 8); bytes[i++] = (byte)((this._UncompressedSize & 0xff0000) >> 0x10); bytes[i++] = (byte)((this._UncompressedSize & 0xff000000L) >> 0x18); bytes[i++] = (byte)(filenameLength & 0xff); bytes[i++] = (byte)((filenameLength & 0xff00) >> 8); byte[] extra = null; short ExtraFieldLength = (extra == null) ? ((short)0) : ((short)extra.Length); bytes[i++] = (byte)(ExtraFieldLength & 0xff); bytes[i++] = (byte)((ExtraFieldLength & 0xff00) >> 8); int j = 0; j = 0; while ((j < FileNameBytes.Length) && ((i + j) < bytes.Length)) { bytes[i + j] = FileNameBytes[j]; j++; } i += j; if (extra != null) { j = 0; while (j < extra.Length) { bytes[i + j] = extra[j]; j++; } i += j; } CountingStream counter = s as CountingStream; this._RelativeOffsetOfHeader = (counter != null) ? counter.BytesWritten : ((int)s.Position); this._LengthOfHeader = i; s.Write(bytes, 0, i); this._EntryHeader = new byte[i]; for (j = 0; j < i; j++) { this._EntryHeader[j] = bytes[j]; } }
private static bool ReadHeader(ZipEntry ze, Encoding defaultEncoding) { // no seek - stream integrity should be protected by the caller int bytesRead = 0; ze._RelativeOffsetOfHeader = (int)ze.ArchiveStream.Position; int signature = ZipSharedUtilities.ReadSignature(ze.ArchiveStream); bytesRead += 4; if (IsNotValidSig(signature)) { ze.ArchiveStream.Seek(-4L, SeekOrigin.Current); if (ZipDirEntry.IsNotValidSig(signature) && (signature != 0x6054b50L)) { throw new BadReadException(String.Format(" ZipEntry::ReadHeader(): Bad signature (0x{0:X8}) at position 0x{1:X8}", signature, ze.ArchiveStream.Position)); } return(false); } byte[] block = new byte[0x1a]; int n = ze.ArchiveStream.Read(block, 0, block.Length); if (n != block.Length) { return(false); } bytesRead += n; int i = 0; ze._VersionNeeded = (short)(block[i++] + (block[i++] * 0x100)); ze._BitField = (short)(block[i++] + (block[i++] * 0x100)); ze._CompressionMethod = (short)(block[i++] + (block[i++] * 0x100)); ze._TimeBlob = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100); ze._LastModified = ZipSharedUtilities.PackedToDateTime(ze._TimeBlob); if ((ze._BitField & 8) != 8) { ze._Crc32 = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100); ze._CompressedSize = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100); ze._UncompressedSize = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100); } else { i += 12; } short filenameLength = (short)(block[i++] + (block[i++] * 0x100)); short extraFieldLength = (short)(block[i++] + (block[i++] * 0x100)); block = new byte[filenameLength]; n = ze.ArchiveStream.Read(block, 0, block.Length); bytesRead += n; var s1 = ZipSharedUtilities.StringFromBuffer(block, block.Length, Encoding.GetEncoding(1251)); var s2 = ZipSharedUtilities.StringFromBuffer(block, block.Length, Encoding.ASCII); var s3 = ZipSharedUtilities.StringFromBuffer(block, block.Length, Encoding.UTF8); var s4 = ZipSharedUtilities.StringFromBuffer(block, block.Length, Encoding.Default); var s5 = ZipSharedUtilities.StringFromBuffer(block, block.Length, Encoding.GetEncoding(1252)); if ((ze._BitField & 0x800) == 0x800) { ze._FileNameInArchive = ZipSharedUtilities.StringFromBuffer(block, block.Length, Encoding.UTF8); ze.UseUtf8Encoding = true; } else { ze._FileNameInArchive = ZipSharedUtilities.StringFromBuffer(block, block.Length, defaultEncoding); ze._encoding = defaultEncoding; } ze._LocalFileName = ze._FileNameInArchive; if (extraFieldLength > 0) { ze._Extra = new byte[extraFieldLength]; n = ze.ArchiveStream.Read(ze._Extra, 0, ze._Extra.Length); bytesRead += n; } if (!ze.FileName.EndsWith("/") && ((ze._BitField & 8) == 8)) { long posn = ze.ArchiveStream.Position; bool wantMore = true; long SizeOfDataRead = 0L; int tries = 0; while (wantMore) { tries++; long d = ZipSharedUtilities.FindSignature(ze.ArchiveStream, 0x8074b50); if (d == -1L) { return(false); } SizeOfDataRead += d; block = new byte[12]; n = ze.ArchiveStream.Read(block, 0, block.Length); if (n != 12) { return(false); } bytesRead += n; i = 0; ze._Crc32 = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100); ze._CompressedSize = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100); ze._UncompressedSize = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100); if (SizeOfDataRead != ze._CompressedSize) { ze.ArchiveStream.Seek(-12L, SeekOrigin.Current); SizeOfDataRead += 4L; } } ze.ArchiveStream.Seek(posn, SeekOrigin.Begin); } ze._CompressedFileDataSize = ze._CompressedSize; if ((ze._BitField & 1) == 1) { throw new NotSupportedException("Encryption is not supported"); } ze._TotalEntrySize = bytesRead + ze._CompressedFileDataSize; ze._LengthOfHeader = bytesRead; return(true); }
internal static ZipEntry Create(String filename, String nameInArchive, Stream stream) { if (String.IsNullOrEmpty(filename)) { throw new ZipException("The entry name must be non-null and non-empty."); } ZipEntry entry = new ZipEntry(); if (stream != null) { entry._sourceStream = stream; entry._LastModified = DateTime.Now; } else { entry._LastModified = (File.Exists(filename) || Directory.Exists(filename)) ? ZipSharedUtilities.RoundToEvenSecond(File.GetLastWriteTime(filename)) : DateTime.Now; if (!(entry._LastModified.IsDaylightSavingTime() || !DateTime.Now.IsDaylightSavingTime())) { entry._LastModified += new TimeSpan(1, 0, 0); } if (!(!entry._LastModified.IsDaylightSavingTime() || DateTime.Now.IsDaylightSavingTime())) { entry._LastModified -= new TimeSpan(1, 0, 0); } } entry._LocalFileName = filename; entry._FileNameInArchive = nameInArchive.Replace('\\', '/'); return(entry); }
public static ZipDirEntry Read(Stream s, Encoding expectedEncoding) { int signature = ZipSharedUtilities.ReadSignature(s); if (IsNotValidSig(signature)) { s.Seek(-4L, SeekOrigin.Current); if (signature != 0x6054b50L) { throw new BadReadException(String.Format(" ZipDirEntry::Read(): Bad signature ({0:X8}) at position 0x{1:X8}", signature, s.Position)); } return(null); } byte[] block = new byte[0x2a]; if (s.Read(block, 0, block.Length) != block.Length) { return(null); } int i = 0; ZipDirEntry zde = new ZipDirEntry(); short versionMadeBy = (short)(block[i++] + (block[i++] * 0x100)); short versionNeeded = (short)(block[i++] + (block[i++] * 0x100)); short bitField = (short)(block[i++] + (block[i++] * 0x100)); short compressionMethod = (short)(block[i++] + (block[i++] * 0x100)); int lastModDateTime = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100); int crc32 = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100); int compressedSize = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100); int uncompressedSize = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100); short filenameLength = (short)(block[i++] + (block[i++] * 0x100)); short extraFieldLength = (short)(block[i++] + (block[i++] * 0x100)); short commentLength = (short)(block[i++] + (block[i++] * 0x100)); i += 2; zde._InternalFileAttrs = (short)(block[i++] + (block[i++] * 0x100)); zde._ExternalFileAttrs = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100); block = new byte[filenameLength]; int n = s.Read(block, 0, block.Length); if ((bitField & 0x800) == 0x800) { zde._FileName = ZipSharedUtilities.Utf8StringFromBuffer(block, block.Length); } else { zde._FileName = ZipSharedUtilities.StringFromBuffer(block, block.Length, expectedEncoding); } if (extraFieldLength > 0) { zde._Extra = new byte[extraFieldLength]; n = s.Read(zde._Extra, 0, zde._Extra.Length); } if (commentLength > 0) { block = new byte[commentLength]; n = s.Read(block, 0, block.Length); if ((bitField & 0x800) == 0x800) { zde._Comment = ZipSharedUtilities.Utf8StringFromBuffer(block, block.Length); } else { zde._Comment = ZipSharedUtilities.StringFromBuffer(block, block.Length, expectedEncoding); } } return(zde); }