Ejemplo n.º 1
0
        public GZIPHeader Clone()
        {
            var gheader = new GZIPHeader();

            byte[] tmp;
            if (gheader.extra != null)
            {
                tmp = new byte[gheader.extra.Length];
                Array.Copy(gheader.extra, 0, tmp, 0, tmp.Length);
                gheader.extra = tmp;
            }

            if (gheader.name != null)
            {
                tmp = new byte[gheader.name.Length];
                Array.Copy(gheader.name, 0, tmp, 0, tmp.Length);
                gheader.name = tmp;
            }

            if (gheader.comment != null)
            {
                tmp = new byte[gheader.comment.Length];
                Array.Copy(gheader.comment, 0, tmp, 0, tmp.Length);
                gheader.comment = tmp;
            }

            return(gheader);
        }
Ejemplo n.º 2
0
        internal int Inflate_I(int f)
        {
            //int hold = 0;

            int r;
            int b;

            if (z == null || z.next_in == null)
            {
                if (f == Z_FINISH && this.mode == HEAD)
                {
                    return(Z_OK);
                }
                return(Z_STREAM_ERROR);
            }

            f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
            r = Z_BUF_ERROR;
            while (true)
            {
                if (mode == HEAD)
                {
                    if (wrap == 0)
                    {
                        this.mode = BLOCKS;
                        continue; // break;
                    }

                    try { r = ReadBytes(2, r, f); }
                    catch (Return e) { return(e.r); }

                    if ((wrap == 4 || (wrap & 2) != 0) &&
                        this.need == 0x8b1fL) // gzip header
                    {
                        if (wrap == 4)
                        {
                            wrap = 2;
                        }
                        z.adler = new CRC32();
                        Checksum(2, this.need);

                        if (gheader == null)
                        {
                            gheader = new GZIPHeader();
                        }

                        this.mode = FLAGS;
                        continue; // break;
                    }

                    if ((wrap & 2) != 0)
                    {
                        this.mode = BAD;
                        z.msg     = "incorrect header check";
                        continue; // break;
                    }

                    flags = 0;

                    this.method = ((int)this.need) & 0xff;
                    b           = ((int)(this.need >> 8)) & 0xff;

                    if (((wrap & 1) == 0 || // check if zlib header allowed
                         (((this.method << 8) + b) % 31) != 0) &&
                        (this.method & 0xf) != Z_DEFLATED)
                    {
                        if (wrap == 4)
                        {
                            z.next_in_index -= 2;
                            z.avail_in      += 2;
                            z.total_in      -= 2;
                            wrap             = 0;
                            this.mode        = BLOCKS;
                            continue; // break;
                        }
                        this.mode = BAD;
                        z.msg     = "incorrect header check";
                        // since zlib 1.2, it is allowted to inflateSync for this case.

                        /*
                         * this.marker = 5;       // can't try inflateSync
                         */
                        continue; // break;
                    }

                    if ((this.method & 0xf) != Z_DEFLATED)
                    {
                        this.mode = BAD;
                        z.msg     = "unknown compression method";
                        // since zlib 1.2, it is allowted to inflateSync for this case.

                        /*
                         *  this.marker = 5;       // can't try inflateSync
                         */
                        continue; // break;
                    }

                    if (wrap == 4)
                    {
                        wrap = 1;
                    }

                    if ((this.method >> 4) + 8 > this.wbits)
                    {
                        this.mode = BAD;
                        z.msg     = "invalid window size";
                        // since zlib 1.2, it is allowted to inflateSync for this case.

                        /*
                         *  this.marker = 5;       // can't try inflateSync
                         */
                        continue; // break;
                    }

                    z.adler = new Adler32();

                    if ((b & PRESET_DICT) == 0)
                    {
                        this.mode = BLOCKS;
                        continue; // break;
                    }
                    this.mode = DICT4;
                } // case HEAD
                if (this.mode == DICT4)
                {
                    if (z.avail_in == 0)
                    {
                        return(r);
                    }
                    r = f;

                    z.avail_in--;
                    z.total_in++;
                    this.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & 0xff000000L;
                    this.mode = DICT3;
                } // case DICT4
                if (this.mode == DICT3)
                {
                    if (z.avail_in == 0)
                    {
                        return(r);
                    }
                    r = f;

                    z.avail_in--;
                    z.total_in++;
                    this.need += ((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L;
                    this.mode  = DICT2;
                } // case DICT3
                if (this.mode == DICT2)
                {
                    if (z.avail_in == 0)
                    {
                        return(r);
                    }
                    r = f;

                    z.avail_in--;
                    z.total_in++;
                    this.need += ((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L;
                    this.mode  = DICT1;
                } // case DICT2
                if (this.mode == DICT1)
                {
                    if (z.avail_in == 0)
                    {
                        return(r);
                    }
                    r = f;

                    z.avail_in--;
                    z.total_in++;
                    this.need += (z.next_in[z.next_in_index++] & 0xffL);
                    z.adler.Reset(this.need);
                    this.mode = DICT0;
                    return(Z_NEED_DICT);
                } // case DICT1
                if (this.mode == DICT0)
                {
                    this.mode   = BAD;
                    z.msg       = "need dictionary";
                    this.marker = 0; // can try inflateSync
                    return(Z_STREAM_ERROR);
                } // case DICT0
                if (this.mode == BLOCKS)
                {
                    r = this.blocks.Proc(r);
                    if (r == Z_DATA_ERROR)
                    {
                        this.mode   = BAD;
                        this.marker = 0; // can try inflateSync
                        continue;        // break;
                    }
                    if (r == Z_OK)
                    {
                        r = f;
                    }
                    if (r != Z_STREAM_END)
                    {
                        return(r);
                    }
                    r        = f;
                    this.was = z.adler.GetValue();
                    this.blocks.Reset();
                    if (this.wrap == 0)
                    {
                        this.mode = DONE;
                        continue; // break;
                    }
                    this.mode = CHECK4;
                } // case BLOCKS
                if (this.mode == CHECK4)
                {
                    if (z.avail_in == 0)
                    {
                        return(r);
                    }
                    r = f;

                    z.avail_in--;
                    z.total_in++;
                    this.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & 0xff000000L;
                    this.mode = CHECK3;
                } // case CHECK4
                if (this.mode == CHECK3)
                {
                    if (z.avail_in == 0)
                    {
                        return(r);
                    }
                    r = f;

                    z.avail_in--;
                    z.total_in++;
                    this.need += ((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L;
                    this.mode  = CHECK2;
                } // case CHECK3
                if (this.mode == CHECK2)
                {
                    if (z.avail_in == 0)
                    {
                        return(r);
                    }
                    r = f;

                    z.avail_in--;
                    z.total_in++;
                    this.need += ((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L;
                    this.mode  = CHECK1;
                } // case CHECK2
                if (this.mode == CHECK1)
                {
                    if (z.avail_in == 0)
                    {
                        return(r);
                    }
                    r = f;

                    z.avail_in--;
                    z.total_in++;
                    this.need += (z.next_in[z.next_in_index++] & 0xffL);

                    if (flags != 0)
                    {
                        // gzip
                        this.need = ((this.need & 0xff000000) >> 24 |
                                     (this.need & 0x00ff0000) >> 8 |
                                     (this.need & 0x0000ff00) << 8 |
                                     (this.need & 0x0000ffff) << 24) & 0xffffffffL;
                    }

                    if (((int)(this.was)) != ((int)(this.need)))
                    {
                        z.msg = "incorrect data check";
                        // chack is delayed

                        /*
                         * this.mode = BAD;
                         * this.marker = 5;       // can't try inflateSync
                         * break;
                         */
                    }
                    else if (flags != 0 && gheader != null)
                    {
                        gheader.crc = this.need;
                    }

                    this.mode = LENGTH;
                } // case CHECK1
                if (this.mode == LENGTH)
                {
                    if (wrap != 0 && flags != 0)
                    {
                        try  { r = ReadBytes(4, r, f); }
                        catch (Return e) { return(e.r); }

                        if (z.msg != null && z.msg.Equals("incorrect data check"))
                        {
                            this.mode   = BAD;
                            this.marker = 5; // can't try inflateSync
                            continue;        // break;
                        }

                        if (this.need != (z.total_out & 0xffffffffL))
                        {
                            z.msg     = "incorrect length check";
                            this.mode = BAD;
                            continue; // break;
                        }
                        z.msg = null;
                    }
                    else
                    {
                        if (z.msg != null && z.msg.Equals("incorrect data check"))
                        {
                            this.mode   = BAD;
                            this.marker = 5; // can't try inflateSync
                            continue;        // break;
                        }
                    }

                    this.mode = DONE;
                } // case LENGTH
                if (this.mode == DONE)
                {
                    return(Z_STREAM_END);
                }
                if (this.mode == BAD)
                {
                    return(Z_DATA_ERROR);
                }
                if (this.mode == FLAGS)
                {
                    try  { r = ReadBytes(2, r, f); }
                    catch (Return e) { return(e.r); }

                    flags = ((int)this.need) & 0xffff;

                    if ((flags & 0xff) != Z_DEFLATED)
                    {
                        z.msg     = "unknown compression method";
                        this.mode = BAD;
                        continue; // break;
                    }
                    if ((flags & 0xe000) != 0)
                    {
                        z.msg     = "unknown header flags set";
                        this.mode = BAD;
                        continue; // break;
                    }

                    if ((flags & 0x0200) != 0)
                    {
                        Checksum(2, this.need);
                    }

                    this.mode = TIME;
                } // case FLAGS
                if (this.mode == TIME)
                {
                    try
                    {
                        r = ReadBytes(4, r, f);
                    }
                    catch (Return e)
                    {
                        return(e.r);
                    }
                    if (gheader != null)
                    {
                        gheader.time = this.need;
                    }
                    if ((flags & 0x0200) != 0)
                    {
                        Checksum(4, this.need);
                    }
                    this.mode = OS;
                } // case TIME
                if (this.mode == OS)
                {
                    try
                    {
                        r = ReadBytes(2, r, f);
                    }
                    catch (Return e)
                    {
                        return(e.r);
                    }
                    if (gheader != null)
                    {
                        gheader.xflags = ((int)this.need) & 0xff;
                        gheader.os     = (((int)this.need) >> 8) & 0xff;
                    }
                    if ((flags & 0x0200) != 0)
                    {
                        Checksum(2, this.need);
                    }
                    this.mode = EXLEN;
                } // case OS
                if (this.mode == EXLEN)
                {
                    if ((flags & 0x0400) != 0)
                    {
                        try
                        {
                            r = ReadBytes(2, r, f);
                        }
                        catch (Return e)
                        {
                            return(e.r);
                        }
                        if (gheader != null)
                        {
                            gheader.extra = new byte[((int)this.need) & 0xffff];
                        }
                        if ((flags & 0x0200) != 0)
                        {
                            Checksum(2, this.need);
                        }
                    }
                    else if (gheader != null)
                    {
                        gheader.extra = null;
                    }
                    this.mode = EXTRA;
                } // case EXLEN
                if (this.mode == EXTRA)
                {
                    if ((flags & 0x0400) != 0)
                    {
                        try
                        {
                            r = ReadBytes(r, f);
                            if (gheader != null)
                            {
                                byte[] foo = tmp_string.ToArray();
                                tmp_string = null;
                                if (foo.Length == gheader.extra.Length)
                                {
                                    Array.Copy(foo, 0, gheader.extra, 0, foo.Length);
                                }
                                else
                                {
                                    z.msg     = "bad extra field length";
                                    this.mode = BAD;
                                    continue; // break;
                                }
                            }
                        }
                        catch (Return e)
                        {
                            return(e.r);
                        }
                    }
                    else if (gheader != null)
                    {
                        gheader.extra = null;
                    }
                    this.mode = NAME;
                } // case EXTRA
                if (this.mode == NAME)
                {
                    if ((flags & 0x0800) != 0)
                    {
                        try
                        {
                            r = ReadString(r, f);
                            if (gheader != null)
                            {
                                gheader.name = tmp_string.ToArray();
                            }
                            tmp_string = null;
                        }
                        catch (Return e)
                        {
                            return(e.r);
                        }
                    }
                    else if (gheader != null)
                    {
                        gheader.name = null;
                    }
                    this.mode = COMMENT;
                } // case NAME
                if (this.mode == COMMENT)
                {
                    if ((flags & 0x1000) != 0)
                    {
                        try
                        {
                            r = ReadString(r, f);
                            if (gheader != null)
                            {
                                gheader.comment = tmp_string.ToArray();
                            }
                            tmp_string = null;
                        }
                        catch (Return e)
                        {
                            return(e.r);
                        }
                    }
                    else if (gheader != null)
                    {
                        gheader.comment = null;
                    }
                    this.mode = HCRC;
                } // case COMMENT
                if (this.mode == HCRC)
                {
                    if ((flags & 0x0200) != 0)
                    {
                        try { r = ReadBytes(2, r, f); }
                        catch (Return e) { return(e.r); }
                        if (gheader != null)
                        {
                            gheader.hcrc = (int)(this.need & 0xffff);
                        }
                        if (this.need != (z.adler.GetValue() & 0xffffL))
                        {
                            this.mode   = BAD;
                            z.msg       = "header crc mismatch";
                            this.marker = 5; // can't try inflateSync
                            continue;        // break;
                        }
                    }
                    z.adler   = new CRC32();
                    this.mode = BLOCKS;
                    continue; // break;
                } // case HCRC

                // BAD
                // Default
                break;
            }

            // Default
            return(Z_STREAM_ERROR);
        }