コード例 #1
0
ファイル: TarHeader.Read.cs プロジェクト: mikem8361/runtime
        // Reads attributes specific to the GNU format.
        // Throws if any conversion fails.
        private void ReadGnuAttributes(Span <byte> buffer)
        {
            // Convert byte arrays
            long aTime = (long)TarHelpers.ParseOctal <ulong>(buffer.Slice(FieldLocations.ATime, FieldLengths.ATime));

            _aTime = TarHelpers.GetDateTimeOffsetFromSecondsSinceEpoch(aTime);

            long cTime = (long)TarHelpers.ParseOctal <ulong>(buffer.Slice(FieldLocations.CTime, FieldLengths.CTime));

            _cTime = TarHelpers.GetDateTimeOffsetFromSecondsSinceEpoch(cTime);

            // TODO: Read the bytes of the currently unsupported GNU fields, in case user wants to write this entry into another GNU archive, they need to be preserved. https://github.com/dotnet/runtime/issues/68230
        }
コード例 #2
0
ファイル: TarHeader.Read.cs プロジェクト: mikem8361/runtime
        // Reads the attributes shared by the POSIX and GNU formats.
        // Throws if converting the bytes to their expected data type fails.
        private void ReadPosixAndGnuSharedAttributes(Span <byte> buffer)
        {
            // Convert the byte arrays
            _uName = TarHelpers.GetTrimmedAsciiString(buffer.Slice(FieldLocations.UName, FieldLengths.UName));
            _gName = TarHelpers.GetTrimmedAsciiString(buffer.Slice(FieldLocations.GName, FieldLengths.GName));

            // DevMajor and DevMinor only have values with character devices and block devices.
            // For all other typeflags, the values in these fields are irrelevant.
            if (_typeFlag is TarEntryType.CharacterDevice or TarEntryType.BlockDevice)
            {
                // Major number for a character device or block device entry.
                _devMajor = (int)TarHelpers.ParseOctal <uint>(buffer.Slice(FieldLocations.DevMajor, FieldLengths.DevMajor));

                // Minor number for a character device or block device entry.
                _devMinor = (int)TarHelpers.ParseOctal <uint>(buffer.Slice(FieldLocations.DevMinor, FieldLengths.DevMinor));
            }
        }
コード例 #3
0
ファイル: TarHeader.Read.cs プロジェクト: mikem8361/runtime
        // Attempts to read the fields shared by all formats and stores them in their expected data type.
        // Throws if any data type conversion fails.
        // Returns true on success, false if checksum is zero.
        private static TarHeader?TryReadCommonAttributes(Span <byte> buffer, TarEntryFormat initialFormat)
        {
            // Start by collecting fields that need special checks that return early when data is wrong

            // Empty checksum means this is an invalid (all blank) entry, finish early
            Span <byte> spanChecksum = buffer.Slice(FieldLocations.Checksum, FieldLengths.Checksum);

            if (TarHelpers.IsAllNullBytes(spanChecksum))
            {
                return(null);
            }
            int checksum = (int)TarHelpers.ParseOctal <uint>(spanChecksum);

            // Zero checksum means the whole header is empty
            if (checksum == 0)
            {
                return(null);
            }

            long size = (int)TarHelpers.ParseOctal <uint>(buffer.Slice(FieldLocations.Size, FieldLengths.Size));

            if (size < 0)
            {
                throw new FormatException(string.Format(SR.TarSizeFieldNegative));
            }

            // Continue with the rest of the fields that require no special checks
            TarHeader header = new(initialFormat,
                                   name : TarHelpers.GetTrimmedUtf8String(buffer.Slice(FieldLocations.Name, FieldLengths.Name)),
                                   mode : (int)TarHelpers.ParseOctal <uint>(buffer.Slice(FieldLocations.Mode, FieldLengths.Mode)),
                                   mTime : TarHelpers.GetDateTimeOffsetFromSecondsSinceEpoch((long)TarHelpers.ParseOctal <ulong>(buffer.Slice(FieldLocations.MTime, FieldLengths.MTime))),
                                   typeFlag : (TarEntryType)buffer[FieldLocations.TypeFlag])
            {
                _checksum = checksum,
                _size     = size,
                _uid      = (int)TarHelpers.ParseOctal <uint>(buffer.Slice(FieldLocations.Uid, FieldLengths.Uid)),
                _gid      = (int)TarHelpers.ParseOctal <uint>(buffer.Slice(FieldLocations.Gid, FieldLengths.Gid)),
                _linkName = TarHelpers.GetTrimmedUtf8String(buffer.Slice(FieldLocations.LinkName, FieldLengths.LinkName))
            };

            if (header._format == TarEntryFormat.Unknown)
            {
                header._format = header._typeFlag switch
                {
                    TarEntryType.ExtendedAttributes or
                    TarEntryType.GlobalExtendedAttributes => TarEntryFormat.Pax,

                                 TarEntryType.DirectoryList or
                                 TarEntryType.LongLink or
                                 TarEntryType.LongPath or
                                 TarEntryType.MultiVolume or
                                 TarEntryType.RenamedOrSymlinked or
                                 TarEntryType.TapeVolume => TarEntryFormat.Gnu,

                    // V7 is the only one that uses 'V7RegularFile'.
                                 TarEntryType.V7RegularFile => TarEntryFormat.V7,

                                 TarEntryType.SparseFile => throw new NotSupportedException(string.Format(SR.TarEntryTypeNotSupported, header._typeFlag)),

                          // We can quickly determine the *minimum* possible format if the entry type
                          // is the POSIX 'RegularFile', although later we could upgrade it to PAX or GNU
                          _ => (header._typeFlag == TarEntryType.RegularFile) ? TarEntryFormat.Ustar : TarEntryFormat.V7
                };
            }

            return(header);
        }