コード例 #1
0
ファイル: ZipRead.cs プロジェクト: artifexor/RVWorld
        private ZipReturn ZipFileReadHeaders()
        {
            try
            {
                ZipReturn zRet = FindEndOfCentralDirSignature();
                if (zRet != ZipReturn.ZipGood)
                {
                    ZipFileClose();
                    return(zRet);
                }

                ulong endOfCentralDir = (ulong)_zipFs.Position;
                zRet = EndOfCentralDirRead();
                if (zRet != ZipReturn.ZipGood)
                {
                    ZipFileClose();
                    return(zRet);
                }

                // check if ZIP64 header is required
                bool zip64Required = (_centralDirStart == 0xffffffff || _centralDirSize == 0xffffffff || _localFilesCount == 0xffff);

                // check for a ZIP64 header
                _zipFs.Position = (long)endOfCentralDir - 20;
                zRet            = Zip64EndOfCentralDirectoryLocatorRead();
                if (zRet == ZipReturn.ZipGood)
                {
                    _zipFs.Position = (long)_endOfCentralDir64;
                    zRet            = Zip64EndOfCentralDirRead();
                    if (zRet == ZipReturn.ZipGood)
                    {
                        _zip64          = true;
                        endOfCentralDir = _endOfCentralDir64;
                    }
                }

                if (zip64Required && !_zip64)
                {
                    return(ZipReturn.Zip64EndOfCentralDirError);
                }

                offset = (endOfCentralDir - _centralDirSize) - _centralDirStart;

                _centralDirStart += offset;

                bool trrntzip = false;

                // check if the ZIP has a valid TorrentZip file comment
                if (FileComment.Length == 22)
                {
                    if (CompressUtils.GetString(FileComment).Substring(0, 14) == "TORRENTZIPPED-")
                    {
                        CrcCalculatorStream crcCs = new(_zipFs, true);
                        byte[] buffer             = new byte[_centralDirSize];
                        _zipFs.Position = (long)_centralDirStart;
                        crcCs.Read(buffer, 0, (int)_centralDirSize);
                        crcCs.Flush();
                        crcCs.Close();

                        uint r = (uint)crcCs.Crc;
                        crcCs.Dispose();

                        string tcrc = CompressUtils.GetString(FileComment).Substring(14, 8);
                        string zcrc = r.ToString("X8");
                        if (string.Compare(tcrc, zcrc, StringComparison.Ordinal) == 0)
                        {
                            trrntzip = true;
                        }
                    }
                }

                if (zip64Required != _zip64)
                {
                    trrntzip = false;
                }

                // now read the central directory
                _zipFs.Position = (long)_centralDirStart;

                _localFiles.Clear();
                _localFiles.Capacity = (int)_localFilesCount;
                for (int i = 0; i < _localFilesCount; i++)
                {
                    ZipLocalFile lc = new();
                    zRet = lc.CentralDirectoryRead(_zipFs, offset);
                    if (zRet != ZipReturn.ZipGood)
                    {
                        ZipFileClose();
                        return(zRet);
                    }
                    _zip64 |= lc.GetStatus(LocalFileStatus.Zip64);
                    _localFiles.Add(lc);
                }

                for (int i = 0; i < _localFilesCount; i++)
                {
                    zRet = _localFiles[i].LocalFileHeaderRead(_zipFs);
                    if (zRet != ZipReturn.ZipGood)
                    {
                        ZipFileClose();
                        return(zRet);
                    }
                    trrntzip &= _localFiles[i].GetStatus(LocalFileStatus.TrrntZip);
                }

                // check trrntzip file order
                if (trrntzip)
                {
                    for (int i = 0; i < _localFilesCount - 1; i++)
                    {
                        if (CompressUtils.TrrntZipStringCompare(_localFiles[i].Filename, _localFiles[i + 1].Filename) < 0)
                        {
                            continue;
                        }
                        trrntzip = false;
                        break;
                    }
                }

                // check trrntzip directories
                if (trrntzip)
                {
                    for (int i = 0; i < _localFilesCount - 1; i++)
                    {
                        // see if we found a directory
                        string filename0 = _localFiles[i].Filename;
                        if (filename0.Substring(filename0.Length - 1, 1) != "/")
                        {
                            continue;
                        }

                        // see if the next file is in that directory
                        string filename1 = _localFiles[i + 1].Filename;
                        if (filename1.Length <= filename0.Length)
                        {
                            continue;
                        }
                        if (CompressUtils.TrrntZipStringCompare(filename0, filename1.Substring(0, filename0.Length)) != 0)
                        {
                            continue;
                        }

                        // if we found a file in the directory then we do not need the directory entry
                        trrntzip = false;
                        break;
                    }
                }

                if (trrntzip)
                {
                    ZipStatus |= ZipStatus.TrrntZip;
                }

                return(ZipReturn.ZipGood);
            }
            catch
            {
                ZipFileClose();
                return(ZipReturn.ZipErrorReadingFile);
            }
        }
コード例 #2
0
ファイル: ZipWriteStream.cs プロジェクト: artifexor/RVWorld
        /*
         * raw is true if we are just going to copy the raw data stream from the source to the destination zip file
         * trrntzip is thue if the source zip is a valid trrntzip file
         * compressionMethod must be set to 8 to make a valid trrntzip file.
         *
         * if raw is false then compressionMthod must be 0,8 or 93 (zstd)
         */

        public ZipReturn ZipFileOpenWriteStream(bool raw, bool trrntzip, string filename, ulong uncompressedSize, ushort compressionMethod, out Stream stream, TimeStamps timeStamp = null)
        {
            stream = null;
            if (ZipOpen != ZipOpenType.OpenWrite)
            {
                return(ZipReturn.ZipWritingToInputFile);
            }

            ZipReturn validTrrntzip = ZipReturn.ZipGood;

            //invalid torrentZip Input If:
            if (compressionMethod != 8)
            {
                validTrrntzip = ZipReturn.ZipTrrntzipIncorrectCompressionUsed;
            }
            if (raw && !trrntzip)
            {
                validTrrntzip = ZipReturn.ZipTrrntZipIncorrectDataStream;
            }

            int localFilesCount = _localFiles.Count;

            if (localFilesCount > 0)
            {
                // check that filenames are in trrntzip order
                string lastFilename = _localFiles[localFilesCount - 1].Filename;
                if (CompressUtils.TrrntZipStringCompare(lastFilename, filename) > 0)
                {
                    validTrrntzip = ZipReturn.ZipTrrntzipIncorrectFileOrder;
                }

                // check that no un-needed directory entries are added
                if (_localFiles[localFilesCount - 1].IsDirectory && filename.Length > lastFilename.Length)
                {
                    if (CompressUtils.TrrntZipStringCompare(lastFilename, filename.Substring(0, lastFilename.Length)) == 0)
                    {
                        validTrrntzip = ZipReturn.ZipTrrntzipIncorrectDirectoryAddedToZip;
                    }
                }
            }

            // if we are requirering a trrrntzp file and it is not a trrntzip formated supplied stream then error out
            if (writeZipType == OutputZipType.TrrntZip)
            {
                if (validTrrntzip != ZipReturn.ZipGood)
                {
                    return(validTrrntzip);
                }
            }

            ZipLocalFile lf = new ZipLocalFile(filename, timeStamp);

            lf.SetStatus(LocalFileStatus.TrrntZip, validTrrntzip == ZipReturn.ZipGood);

            ZipReturn retVal = lf.LocalFileOpenWriteStream(_zipFs, raw, uncompressedSize, compressionMethod, out stream);

            if (retVal != ZipReturn.ZipGood)
            {
                return(retVal);
            }

            if (filename.Length > 0)
            {
                lf.IsDirectory = (filename.Substring(filename.Length - 1, 1) == "/");
            }

            _compressionStream = stream;
            _localFiles.Add(lf);

            return(ZipReturn.ZipGood);
        }