Exemplo n.º 1
0
        /// <summary>
        /// Reads a block of bytes from the current zip entry.
        /// </summary>
        /// <returns>
        /// the number of bytes read (may be smaller, even before EOF), or -1 on EOF.
        /// </returns>
        /// <exception name="Exception">
        /// IOException if a i/o error occured.
        /// ZipException if the deflated stream is corrupted.
        /// </exception>
        public override int Read(byte[] b, int off, int len)
        {
            if (crc == null)
            {
                throw new InvalidOperationException("Closed.");
            }

            if (entry == null)
            {
                return(-1);
            }
            bool finished = false;

            switch (method)
            {
            case ZipOutputStream.DEFLATED:
                len = base.Read(b, off, len);
                if (len < 0)
                {
                    if (!inf.IsFinished)
                    {
                        throw new ZipException("Inflater not finished!?");
                    }
                    avail = inf.RemainingInput;

                    if (inf.TotalIn != csize || inf.TotalOut != size)
                    {
                        throw new ZipException("size mismatch: " + csize + ";" + size + " <-> " + inf.TotalIn + ";" + inf.TotalOut);
                    }
                    inf.Reset();
                    finished = true;
                }
                break;

            case ZipOutputStream.STORED:
                if (len > csize && csize >= 0)
                {
                    len = (int)csize;
                }
                len = ReadBuf(b, off, len);
                if (len > 0)
                {
                    csize -= len;
                    size  -= len;
                }

                if (csize == 0)
                {
                    finished = true;
                }
                else
                {
                    if (len < 0)
                    {
                        throw new ZipException("EOF in stored block");
                    }
                }

                // decrypting crypted data
                if (cryptbuffer != null)
                {
                    DecryptBlock(b, off, len);
                }

                break;
            }

            if (len > 0)
            {
                crc.Update(b, off, len);
            }

            if (finished)
            {
                if ((flags & 8) != 0)
                {
                    ReadDataDescr();
                }
                //Console.WriteLine("{0:x}",crc.Value & 0xFFFFFFFFL);
                //Console.WriteLine(entry.Crc);

                if ((crc.Value & 0xFFFFFFFFL) != entry.Crc && entry.Crc != -1)
                {
                    throw new ZipException("CRC mismatch");
                }
                crc.Reset();
                entry = null;
            }
            return(len);
        }
Exemplo n.º 2
0
 /// <summary>
 /// Closes the zip file.
 /// </summary>
 /// <exception name="Exception">
 /// if a i/o error occured.
 /// </exception>
 public override void Close()
 {
     base.Close();
     crc   = null;
     entry = null;
 }
Exemplo n.º 3
0
        /// <summary>
        /// Open the next entry from the zip archive, and return its description.
        /// If the previous entry wasn't closed, this method will close it.
        /// </summary>
        public ZipEntry GetNextEntry()
        {
            if (crc == null)
            {
                throw new InvalidOperationException("Closed.");
            }
            if (entry != null)
            {
                CloseEntry();
            }

            int header = ReadLeInt();

            if (header == ZipConstants.CENSIG)
            {
                /* Central Header reached. */
                Close();
                return(null);
            }

            if (header != ZipConstants.LOCSIG)
            {
                throw new ZipException("Wrong Local header signature: 0x" + String.Format("{0:X}", header));
            }

            short version = (short)ReadLeShort();

            flags  = ReadLeShort();
            method = ReadLeShort();
            uint dostime = (uint)ReadLeInt();
            int  crc2    = ReadLeInt();

            csize = ReadLeInt();
            size  = ReadLeInt();
            int  nameLen   = ReadLeShort();
            int  extraLen  = ReadLeShort();
            bool isCrypted = (flags & 1) == 1;

            if (method == ZipOutputStream.STORED && (!isCrypted && csize != size || (isCrypted && csize - 12 != size)))
            {
                throw new ZipException("Stored, but compressed != uncompressed");
            }

            byte[] buffer = new byte[nameLen];
            ReadFully(buffer);

            string name = ZipConstants.ConvertToString(buffer);

            entry           = new ZipEntry(name);
            entry.IsCrypted = isCrypted;
            entry.Version   = (ushort)version;
            if (method != 0 && method != 8)
            {
                throw new ZipException("unknown compression method " + method);
            }
            entry.CompressionMethod = (CompressionMethod)method;

            if ((flags & 8) == 0)
            {
                entry.Crc            = crc2 & 0xFFFFFFFFL;
                entry.Size           = size & 0xFFFFFFFFL;
                entry.CompressedSize = csize & 0xFFFFFFFFL;
            }

            entry.DosTime = dostime;

            if (extraLen > 0)
            {
                byte[] extra = new byte[extraLen];
                ReadFully(extra);
                entry.ExtraData = extra;
            }

            // test for encryption
            if (isCrypted)
            {
                if (password == null)
                {
                    throw new ZipException("No password set.");
                }
                InitializePassword(password);
                cryptbuffer = new byte[12];
                ReadFully(cryptbuffer);
                //crc.Update(cryptbuffer);
                for (int i = 0; i < 12; ++i)
                {
                    cryptbuffer[i] ^= DecryptByte();
                    UpdateKeys(cryptbuffer[i]);
                }
                //cryptbuffer = cryptbuffer2;
                csize -= 12;
            }
            else
            {
                cryptbuffer = null;
            }

            if (method == ZipOutputStream.DEFLATED && avail > 0)
            {
                System.Array.Copy(buf, len - (int)avail, buf, 0, (int)avail);
                len   = (int)avail;
                avail = 0;
                if (isCrypted)
                {
                    DecryptBlock(buf, 0, len);
                }
                inf.SetInput(buf, 0, len);
            }

            return(entry);
        }