Exemplo n.º 1
0
        public bool CheckStructure()
        {
            const int kNumCodersMax = 32; // don't change it
            const int kMaskSize = 32; // it must be >= kNumCodersMax
            const int kNumBindsMax = 32;

            if (Coders.Count > kNumCodersMax || BindPairs.Count > kNumBindsMax)
                return false;

            {
                var v = new BitVector(BindPairs.Count + PackStreams.Count);

                for (int i = 0; i < BindPairs.Count; i++)
                    if (v.GetAndSet(BindPairs[i].InIndex))
                        return false;

                for (int i = 0; i < PackStreams.Count; i++)
                    if (v.GetAndSet(PackStreams[i]))
                        return false;
            }

            {
                var v = new BitVector(UnpackSizes.Count);
                for (int i = 0; i < BindPairs.Count; i++)
                    if (v.GetAndSet(BindPairs[i].OutIndex))
                        return false;
            }

            uint[] mask = new uint[kMaskSize];

            {
                List<int> inStreamToCoder = new List<int>();
                List<int> outStreamToCoder = new List<int>();
                for (int i = 0; i < Coders.Count; i++)
                {
                    CCoderInfo coder = Coders[i];
                    for (int j = 0; j < coder.NumInStreams; j++)
                        inStreamToCoder.Add(i);
                    for (int j = 0; j < coder.NumOutStreams; j++)
                        outStreamToCoder.Add(i);
                }

                for (int i = 0; i < BindPairs.Count; i++)
                {
                    CBindPair bp = BindPairs[i];
                    mask[inStreamToCoder[bp.InIndex]] |= (1u << outStreamToCoder[bp.OutIndex]);
                }
            }

            for (int i = 0; i < kMaskSize; i++)
                for (int j = 0; j < kMaskSize; j++)
                    if (((1u << j) & mask[i]) != 0)
                        mask[i] |= mask[j];

            for (int i = 0; i < kMaskSize; i++)
                if (((1u << i) & mask[i]) != 0)
                    return false;

            return true;
        }
Exemplo n.º 2
0
        private void ReadHeader(ArchiveDatabase db, IPasswordProvider getTextPassword)
        {
            #if DEBUG
            Log.WriteLine("-- ReadHeader --");
            Log.PushIndent();
            #endif
            try
            {
                BlockType? type = ReadId();

                if (type == BlockType.ArchiveProperties)
                {
                    ReadArchiveProperties();
                    type = ReadId();
                }

                List<byte[]> dataVector = null;
                if (type == BlockType.AdditionalStreamsInfo)
                {
                    dataVector = ReadAndDecodePackedStreams(db.StartPositionAfterHeader, getTextPassword);
                    type = ReadId();
                }

                List<long> unpackSizes;
                List<uint?> digests;

                if (type == BlockType.MainStreamsInfo)
                {
                    ReadStreamsInfo(dataVector,
                                    out db.DataStartPosition,
                                    out db.PackSizes,
                                    out db.PackCRCs,
                                    out db.Folders,
                                    out db.NumUnpackStreamsVector,
                                    out unpackSizes,
                                    out digests);

                    db.DataStartPosition += db.StartPositionAfterHeader;
                    type = ReadId();
                }
                else
                {
                    unpackSizes = new List<long>(db.Folders.Count);
                    digests = new List<uint?>(db.Folders.Count);
                    db.NumUnpackStreamsVector = new List<int>(db.Folders.Count);
                    for (int i = 0; i < db.Folders.Count; i++)
                    {
                        var folder = db.Folders[i];
                        unpackSizes.Add(folder.GetUnpackSize());
                        digests.Add(folder.UnpackCRC);
                        db.NumUnpackStreamsVector.Add(1);
                    }
                }

                db.Files.Clear();

                if (type == BlockType.End)
                    return;

                if (type != BlockType.FilesInfo)
                    throw new InvalidOperationException();

                int numFiles = ReadNum();
            #if DEBUG
                Log.WriteLine("NumFiles: " + numFiles);
            #endif
                db.Files = new List<CFileItem>(numFiles);
                for (int i = 0; i < numFiles; i++)
                    db.Files.Add(new CFileItem());

                BitVector emptyStreamVector = new BitVector(numFiles);
                BitVector emptyFileVector = null;
                BitVector antiFileVector = null;
                int numEmptyStreams = 0;

                for (; ; )
                {
                    type = ReadId();
                    if (type == BlockType.End)
                        break;

                    long size = checked((long)ReadNumber()); // TODO: throw invalid data on negative
                    int oldPos = _currentReader.Offset;
                    switch (type)
                    {
                        case BlockType.Name:
                            using (var streamSwitch = new CStreamSwitch())
                            {
                                streamSwitch.Set(this, dataVector);
            #if DEBUG
                                Log.Write("FileNames:");
            #endif
                                for (int i = 0; i < db.Files.Count; i++)
                                {
                                    db.Files[i].Name = _currentReader.ReadString();
            #if DEBUG
                                    Log.Write("  " + db.Files[i].Name);
            #endif
                                }
            #if DEBUG
                                Log.WriteLine();
            #endif
                            }
                            break;
                        case BlockType.WinAttributes:
            #if DEBUG
                            Log.Write("WinAttributes:");
            #endif
                            ReadAttributeVector(dataVector, numFiles, delegate(int i, uint? attr)
                                                                          {
                                                                              db.Files[i].Attrib = attr;
            #if DEBUG
                                                                              Log.Write("  " + (attr.HasValue ? attr.Value.ToString("x8") : "n/a"));
            #endif
                                                                          });
            #if DEBUG
                            Log.WriteLine();
            #endif
                            break;
                        case BlockType.EmptyStream:
                            emptyStreamVector = ReadBitVector(numFiles);
            #if DEBUG

                            Log.Write("EmptyStream: ");
            #endif
                            for (int i = 0; i < emptyStreamVector.Length; i++)
                            {
                                if (emptyStreamVector[i])
                                {
            #if DEBUG
                                    Log.Write("x");
            #endif
                                    numEmptyStreams++;
                                }
                                else
                                {
            #if DEBUG
                                    Log.Write(".");
            #endif
                                }
                            }
            #if DEBUG
                            Log.WriteLine();
            #endif

                            emptyFileVector = new BitVector(numEmptyStreams);
                            antiFileVector = new BitVector(numEmptyStreams);
                            break;
                        case BlockType.EmptyFile:
                            emptyFileVector = ReadBitVector(numEmptyStreams);
            #if DEBUG
                            Log.Write("EmptyFile: ");
                            for (int i = 0; i < numEmptyStreams; i++)
                                Log.Write(emptyFileVector[i] ? "x" : ".");
                            Log.WriteLine();
            #endif
                            break;
                        case BlockType.Anti:
                            antiFileVector = ReadBitVector(numEmptyStreams);
            #if DEBUG
                            Log.Write("Anti: ");
                            for (int i = 0; i < numEmptyStreams; i++)
                                Log.Write(antiFileVector[i] ? "x" : ".");
                            Log.WriteLine();
            #endif
                            break;
                        case BlockType.StartPos:
            #if DEBUG
                            Log.Write("StartPos:");
            #endif
                            ReadNumberVector(dataVector, numFiles, delegate(int i, long? startPos)
                                                                       {
                                                                           db.Files[i].StartPos = startPos;
            #if DEBUG
                                                                           Log.Write("  " + (startPos.HasValue ? startPos.Value.ToString() : "n/a"));
            #endif
                                                                       });
            #if DEBUG
                            Log.WriteLine();
            #endif
                            break;
                        case BlockType.CTime:
            #if DEBUG
                            Log.Write("CTime:");
            #endif
                            ReadDateTimeVector(dataVector, numFiles, delegate(int i, DateTime? time)
                                                                         {
                                                                             db.Files[i].CTime = time;
            #if DEBUG
                                                                             Log.Write("  " + (time.HasValue ? time.Value.ToString() : "n/a"));
            #endif
                                                                         });
            #if DEBUG
                            Log.WriteLine();
            #endif
                            break;
                        case BlockType.ATime:
            #if DEBUG
                            Log.Write("ATime:");
            #endif
                            ReadDateTimeVector(dataVector, numFiles, delegate(int i, DateTime? time)
                                                                         {
                                                                             db.Files[i].ATime = time;
            #if DEBUG
                                                                             Log.Write("  " + (time.HasValue ? time.Value.ToString() : "n/a"));
            #endif
                                                                         });
            #if DEBUG
                            Log.WriteLine();
            #endif
                            break;
                        case BlockType.MTime:
            #if DEBUG
                            Log.Write("MTime:");
            #endif
                            ReadDateTimeVector(dataVector, numFiles, delegate(int i, DateTime? time)
                                                                         {
                                                                             db.Files[i].MTime = time;
            #if DEBUG
                                                                             Log.Write("  " + (time.HasValue ? time.Value.ToString() : "n/a"));
            #endif
                                                                         });
            #if DEBUG
                            Log.WriteLine();
            #endif
                            break;
                        case BlockType.Dummy:
            #if DEBUG
                            Log.Write("Dummy: " + size);
            #endif
                            for (long j = 0; j < size; j++)
                                if (ReadByte() != 0)
                                    throw new InvalidOperationException();
                            break;
                        default:
                            SkipData(size);
                            break;
                    }

                    // since 0.3 record sizes must be correct
                    bool checkRecordsSize = (db.MajorVersion > 0 || db.MinorVersion > 2);
                    if (checkRecordsSize && _currentReader.Offset - oldPos != size)
                        throw new InvalidOperationException();
                }

                int emptyFileIndex = 0;
                int sizeIndex = 0;
                for (int i = 0; i < numFiles; i++)
                {
                    CFileItem file = db.Files[i];
                    file.HasStream = !emptyStreamVector[i];
                    if (file.HasStream)
                    {
                        file.IsDir = false;
                        file.IsAnti = false;
                        file.Size = unpackSizes[sizeIndex];
                        file.Crc = digests[sizeIndex];
                        sizeIndex++;
                    }
                    else
                    {
                        file.IsDir = !emptyFileVector[emptyFileIndex];
                        file.IsAnti = antiFileVector[emptyFileIndex];
                        emptyFileIndex++;
                        file.Size = 0;
                        file.Crc = null;
                    }
                }
            }
            finally
            {
            #if DEBUG
                Log.PopIndent();
            #endif
            }
        }
Exemplo n.º 3
0
        private BitVector ReadBitVector(int length)
        {
            var bits = new BitVector(length);

            byte data = 0;
            byte mask = 0;

            for (int i = 0; i < length; i++)
            {
                if (mask == 0)
                {
                    data = ReadByte();
                    mask = 0x80;
                }

                if ((data & mask) != 0)
                    bits.SetBit(i);

                mask >>= 1;
            }

            return bits;
        }
Exemplo n.º 4
0
 public bool CheckStructure()
 {
     int num;
     int num2;
     if ((this.Coders.Count > 0x20) || (this.BindPairs.Count > 0x20))
     {
         return false;
     }
     BitVector vector = new BitVector(this.BindPairs.Count + this.PackStreams.Count);
     for (num = 0; num < this.BindPairs.Count; num++)
     {
         if (vector.GetAndSet(this.BindPairs[num].InIndex))
         {
             return false;
         }
     }
     for (num = 0; num < this.PackStreams.Count; num++)
     {
         if (vector.GetAndSet(this.PackStreams[num]))
         {
             return false;
         }
     }
     vector = new BitVector(this.UnpackSizes.Count);
     for (num = 0; num < this.BindPairs.Count; num++)
     {
         if (vector.GetAndSet(this.BindPairs[num].OutIndex))
         {
             return false;
         }
     }
     uint[] numArray = new uint[0x20];
     List<int> list = new List<int>();
     List<int> list2 = new List<int>();
     for (num = 0; num < this.Coders.Count; num++)
     {
         CCoderInfo info = this.Coders[num];
         num2 = 0;
         while (num2 < info.NumInStreams)
         {
             list.Add(num);
             num2++;
         }
         num2 = 0;
         while (num2 < info.NumOutStreams)
         {
             list2.Add(num);
             num2++;
         }
     }
     for (num = 0; num < this.BindPairs.Count; num++)
     {
         CBindPair pair = this.BindPairs[num];
         numArray[list[pair.InIndex]] |= ((uint) 1) << list2[pair.OutIndex];
     }
     for (num = 0; num < 0x20; num++)
     {
         for (num2 = 0; num2 < 0x20; num2++)
         {
             if (((((int) 1) << num2) & numArray[num]) != 0)
             {
                 numArray[num] |= numArray[num2];
             }
         }
     }
     for (num = 0; num < 0x20; num++)
     {
         if (((((int) 1) << num) & numArray[num]) != 0)
         {
             return false;
         }
     }
     return true;
 }
Exemplo n.º 5
0
        private void ReadHeader(ArchiveDatabase db, IPasswordProvider getTextPassword)
        {
            Action<int, uint?> action = null;
            Action<int, long?> action2 = null;
            Action<int, DateTime?> action3 = null;
            Action<int, DateTime?> action4 = null;
            Action<int, DateTime?> action5 = null;
            SharpCompress.Compressor.LZMA.Log.WriteLine("-- ReadHeader --");
            SharpCompress.Compressor.LZMA.Log.PushIndent("  ");
            try
            {
                List<long> list2;
                List<uint?> list3;
                int num;
                long num6;
                int num7;
                bool flag2;
                BlockType? nullable = this.ReadId();
                if (((BlockType) nullable) == BlockType.ArchiveProperties)
                {
                    this.ReadArchiveProperties();
                    nullable = this.ReadId();
                }
                List<byte[]> dataVector = null;
                if (((BlockType) nullable) == BlockType.AdditionalStreamsInfo)
                {
                    dataVector = this.ReadAndDecodePackedStreams(db.StartPositionAfterHeader, getTextPassword);
                    nullable = this.ReadId();
                }
                if (((BlockType) nullable) == BlockType.MainStreamsInfo)
                {
                    this.ReadStreamsInfo(dataVector, out db.DataStartPosition, out db.PackSizes, out db.PackCRCs, out db.Folders, out db.NumUnpackStreamsVector, out list2, out list3);
                    db.DataStartPosition += db.StartPositionAfterHeader;
                    nullable = this.ReadId();
                }
                else
                {
                    list2 = new List<long>(db.Folders.Count);
                    list3 = new List<uint?>(db.Folders.Count);
                    db.NumUnpackStreamsVector = new List<int>(db.Folders.Count);
                    for (num = 0; num < db.Folders.Count; num++)
                    {
                        CFolder folder = db.Folders[num];
                        list2.Add(folder.GetUnpackSize());
                        list3.Add(folder.UnpackCRC);
                        db.NumUnpackStreamsVector.Add(1);
                    }
                }
                db.Files.Clear();
                if (((BlockType) nullable) == BlockType.End)
                {
                    return;
                }
                if (((BlockType) nullable) != BlockType.FilesInfo)
                {
                    throw new InvalidOperationException();
                }
                int capacity = this.ReadNum();
                SharpCompress.Compressor.LZMA.Log.WriteLine("NumFiles: " + capacity);
                db.Files = new List<CFileItem>(capacity);
                num = 0;
                while (num < capacity)
                {
                    db.Files.Add(new CFileItem());
                    num++;
                }
                BitVector vector = new BitVector(capacity);
                BitVector vector2 = null;
                BitVector vector3 = null;
                int length = 0;
                goto Label_06FC;
            Label_02DA:
                nullable = this.ReadId();
                if (((BlockType) nullable) == BlockType.End)
                {
                    goto Label_0704;
                }
                long size = (long) this.ReadNumber();
                int offset = this._currentReader.Offset;
                BlockType valueOrDefault = nullable.GetValueOrDefault();
                if (nullable.HasValue)
                {
                    switch (valueOrDefault)
                    {
                        case BlockType.EmptyStream:
                            vector = this.ReadBitVector(capacity);
                            SharpCompress.Compressor.LZMA.Log.Write("EmptyStream: ");
                            num = 0;
                            goto Label_04AD;

                        case BlockType.EmptyFile:
                            vector2 = this.ReadBitVector(length);
                            SharpCompress.Compressor.LZMA.Log.Write("EmptyFile: ");
                            num = 0;
                            goto Label_0519;

                        case BlockType.Anti:
                            vector3 = this.ReadBitVector(length);
                            SharpCompress.Compressor.LZMA.Log.Write("Anti: ");
                            num = 0;
                            goto Label_056E;

                        case BlockType.Name:
                            goto Label_0370;

                        case BlockType.CTime:
                            goto Label_05BC;

                        case BlockType.ATime:
                            goto Label_05F3;

                        case BlockType.MTime:
                            goto Label_062A;

                        case BlockType.WinAttributes:
                            goto Label_0420;

                        case BlockType.StartPos:
                            goto Label_0585;

                        case BlockType.Dummy:
                            SharpCompress.Compressor.LZMA.Log.Write("Dummy: " + size);
                            num6 = 0L;
                            goto Label_0697;
                    }
                }
                goto Label_06A5;
            Label_0370:
                using (CStreamSwitch switch2 = new CStreamSwitch())
                {
                    switch2.Set(this, dataVector);
                    SharpCompress.Compressor.LZMA.Log.Write("FileNames:");
                    num = 0;
                    while (num < db.Files.Count)
                    {
                        db.Files[num].Name = this._currentReader.ReadString();
                        SharpCompress.Compressor.LZMA.Log.Write("  " + db.Files[num].Name);
                        num++;
                    }
                    SharpCompress.Compressor.LZMA.Log.WriteLine();
                }
                goto Label_06B0;
            Label_0420:
                SharpCompress.Compressor.LZMA.Log.Write("WinAttributes:");
                if (action == null)
                {
                    action = delegate (int i, uint? attr) {
                        db.Files[i].Attrib = attr;
                        SharpCompress.Compressor.LZMA.Log.Write("  " + (attr.HasValue ? attr.Value.ToString("x8") : "n/a"));
                    };
                }
                this.ReadAttributeVector(dataVector, capacity, action);
                SharpCompress.Compressor.LZMA.Log.WriteLine();
                goto Label_06B0;
            Label_0471:
                if (vector[num])
                {
                    SharpCompress.Compressor.LZMA.Log.Write("x");
                    length++;
                }
                else
                {
                    SharpCompress.Compressor.LZMA.Log.Write(".");
                }
                num++;
            Label_04AD:
                if (num < vector.Length)
                {
                    goto Label_0471;
                }
                SharpCompress.Compressor.LZMA.Log.WriteLine();
                vector2 = new BitVector(length);
                vector3 = new BitVector(length);
                goto Label_06B0;
            Label_04F5:
                SharpCompress.Compressor.LZMA.Log.Write(vector2[num] ? "x" : ".");
                num++;
            Label_0519:
                if (num < length)
                {
                    goto Label_04F5;
                }
                SharpCompress.Compressor.LZMA.Log.WriteLine();
                goto Label_06B0;
            Label_054A:
                SharpCompress.Compressor.LZMA.Log.Write(vector3[num] ? "x" : ".");
                num++;
            Label_056E:
                if (num < length)
                {
                    goto Label_054A;
                }
                SharpCompress.Compressor.LZMA.Log.WriteLine();
                goto Label_06B0;
            Label_0585:
                SharpCompress.Compressor.LZMA.Log.Write("StartPos:");
                if (action2 == null)
                {
                    action2 = delegate (int i, long? startPos) {
                        db.Files[i].StartPos = startPos;
                        SharpCompress.Compressor.LZMA.Log.Write("  " + (startPos.HasValue ? startPos.Value.ToString() : "n/a"));
                    };
                }
                this.ReadNumberVector(dataVector, capacity, action2);
                SharpCompress.Compressor.LZMA.Log.WriteLine();
                goto Label_06B0;
            Label_05BC:
                SharpCompress.Compressor.LZMA.Log.Write("CTime:");
                if (action3 == null)
                {
                    action3 = delegate (int i, DateTime? time) {
                        db.Files[i].CTime = time;
                        SharpCompress.Compressor.LZMA.Log.Write("  " + (time.HasValue ? time.Value.ToString() : "n/a"));
                    };
                }
                this.ReadDateTimeVector(dataVector, capacity, action3);
                SharpCompress.Compressor.LZMA.Log.WriteLine();
                goto Label_06B0;
            Label_05F3:
                SharpCompress.Compressor.LZMA.Log.Write("ATime:");
                if (action4 == null)
                {
                    action4 = delegate (int i, DateTime? time) {
                        db.Files[i].ATime = time;
                        SharpCompress.Compressor.LZMA.Log.Write("  " + (time.HasValue ? time.Value.ToString() : "n/a"));
                    };
                }
                this.ReadDateTimeVector(dataVector, capacity, action4);
                SharpCompress.Compressor.LZMA.Log.WriteLine();
                goto Label_06B0;
            Label_062A:
                SharpCompress.Compressor.LZMA.Log.Write("MTime:");
                if (action5 == null)
                {
                    action5 = delegate (int i, DateTime? time) {
                        db.Files[i].MTime = time;
                        SharpCompress.Compressor.LZMA.Log.Write("  " + (time.HasValue ? time.Value.ToString() : "n/a"));
                    };
                }
                this.ReadDateTimeVector(dataVector, capacity, action5);
                SharpCompress.Compressor.LZMA.Log.WriteLine();
                goto Label_06B0;
            Label_067B:
                if (this.ReadByte() != 0)
                {
                    throw new InvalidOperationException();
                }
                num6 += 1L;
            Label_0697:
                if (num6 < size)
                {
                    goto Label_067B;
                }
                goto Label_06B0;
            Label_06A5:
                this.SkipData(size);
            Label_06B0:
                if (((db.MajorVersion > 0) || (db.MinorVersion > 2)) && ((this._currentReader.Offset - offset) != size))
                {
                    throw new InvalidOperationException();
                }
            Label_06FC:
                flag2 = true;
                goto Label_02DA;
            Label_0704:
                num7 = 0;
                int num8 = 0;
                for (num = 0; num < capacity; num++)
                {
                    CFileItem item = db.Files[num];
                    item.HasStream = !vector[num];
                    if (item.HasStream)
                    {
                        item.IsDir = false;
                        item.IsAnti = false;
                        item.Size = list2[num8];
                        item.Crc = list3[num8];
                        num8++;
                    }
                    else
                    {
                        item.IsDir = !vector2[num7];
                        item.IsAnti = vector3[num7];
                        num7++;
                        item.Size = 0L;
                        item.Crc = null;
                    }
                }
            }
            finally
            {
                SharpCompress.Compressor.LZMA.Log.PopIndent();
            }
        }
Exemplo n.º 6
0
 private BitVector ReadBitVector(int length)
 {
     BitVector vector = new BitVector(length);
     byte num = 0;
     byte num2 = 0;
     for (int i = 0; i < length; i++)
     {
         if (num2 == 0)
         {
             num = this.ReadByte();
             num2 = 0x80;
         }
         if ((num & num2) != 0)
         {
             vector.SetBit(i);
         }
         num2 = (byte) (num2 >> 1);
     }
     return vector;
 }