reader.mx raw

   1  // Copyright 2009 The Go Authors. All rights reserved.
   2  // Use of this source code is governed by a BSD-style
   3  // license that can be found in the LICENSE file.
   4  
   5  package tar
   6  
   7  import (
   8  	"bytes"
   9  	"io"
  10  	"path/filepath"
  11  	"strconv"
  12  	"time"
  13  )
  14  
  15  // Reader provides sequential access to the contents of a tar archive.
  16  // Reader.Next advances to the next file in the archive (including the first),
  17  // and then Reader can be treated as an io.Reader to access the file's data.
  18  type Reader struct {
  19  	r    io.Reader
  20  	pad  int64      // Amount of padding (ignored) after current file entry
  21  	curr fileReader // Reader for current file entry
  22  	blk  block      // Buffer to use as temporary local storage
  23  
  24  	// err is a persistent error.
  25  	// It is only the responsibility of every exported method of Reader to
  26  	// ensure that this error is sticky.
  27  	err error
  28  }
  29  
  30  type fileReader interface {
  31  	io.Reader
  32  	fileState
  33  
  34  	WriteTo(io.Writer) (int64, error)
  35  }
  36  
  37  // NewReader creates a new [Reader] reading from r.
  38  func NewReader(r io.Reader) *Reader {
  39  	return &Reader{r: r, curr: &regFileReader{r, 0}}
  40  }
  41  
  42  // Next advances to the next entry in the tar archive.
  43  // The Header.Size determines how many bytes can be read for the next file.
  44  // Any remaining data in the current file is automatically discarded.
  45  // At the end of the archive, Next returns the error io.EOF.
  46  //
  47  // If Next encounters a non-local name (as defined by [filepath.IsLocal])
  48  // and the GODEBUG environment variable contains `tarinsecurepath=0`,
  49  // Next returns the header with an [ErrInsecurePath] error.
  50  // A future version of Go may introduce this behavior by default.
  51  // Programs that want to accept non-local names can ignore
  52  // the [ErrInsecurePath] error and use the returned header.
  53  func (tr *Reader) Next() (*Header, error) {
  54  	if tr.err != nil {
  55  		return nil, tr.err
  56  	}
  57  	hdr, err := tr.next()
  58  	tr.err = err
  59  	if err == nil && !filepath.IsLocal(hdr.Name) {
  60  		if tarinsecurepath.Value() == "0" {
  61  			tarinsecurepath.IncNonDefault()
  62  			err = ErrInsecurePath
  63  		}
  64  	}
  65  	return hdr, err
  66  }
  67  
  68  func (tr *Reader) next() (*Header, error) {
  69  	var paxHdrs map[string][]byte
  70  	var gnuLongName, gnuLongLink []byte
  71  
  72  	// Externally, Next iterates through the tar archive as if it is a series of
  73  	// files. Internally, the tar format often uses fake "files" to add meta
  74  	// data that describes the next file. These meta data "files" should not
  75  	// normally be visible to the outside. As such, this loop iterates through
  76  	// one or more "header files" until it finds a "normal file".
  77  	format := FormatUSTAR | FormatPAX | FormatGNU
  78  	for {
  79  		// Discard the remainder of the file and any padding.
  80  		if err := discard(tr.r, tr.curr.physicalRemaining()); err != nil {
  81  			return nil, err
  82  		}
  83  		if _, err := tryReadFull(tr.r, tr.blk[:tr.pad]); err != nil {
  84  			return nil, err
  85  		}
  86  		tr.pad = 0
  87  
  88  		hdr, rawHdr, err := tr.readHeader()
  89  		if err != nil {
  90  			return nil, err
  91  		}
  92  		if err := tr.handleRegularFile(hdr); err != nil {
  93  			return nil, err
  94  		}
  95  		format.mayOnlyBe(hdr.Format)
  96  
  97  		// Check for PAX/GNU special headers and files.
  98  		switch hdr.Typeflag {
  99  		case TypeXHeader, TypeXGlobalHeader:
 100  			format.mayOnlyBe(FormatPAX)
 101  			paxHdrs, err = parsePAX(tr)
 102  			if err != nil {
 103  				return nil, err
 104  			}
 105  			if hdr.Typeflag == TypeXGlobalHeader {
 106  				mergePAX(hdr, paxHdrs)
 107  				return &Header{
 108  					Name:       hdr.Name,
 109  					Typeflag:   hdr.Typeflag,
 110  					Xattrs:     hdr.Xattrs,
 111  					PAXRecords: hdr.PAXRecords,
 112  					Format:     format,
 113  				}, nil
 114  			}
 115  			continue // This is a meta header affecting the next header
 116  		case TypeGNULongName, TypeGNULongLink:
 117  			format.mayOnlyBe(FormatGNU)
 118  			realname, err := readSpecialFile(tr)
 119  			if err != nil {
 120  				return nil, err
 121  			}
 122  
 123  			var p parser
 124  			switch hdr.Typeflag {
 125  			case TypeGNULongName:
 126  				gnuLongName = p.parseString(realname)
 127  			case TypeGNULongLink:
 128  				gnuLongLink = p.parseString(realname)
 129  			}
 130  			continue // This is a meta header affecting the next header
 131  		default:
 132  			// The old GNU sparse format is handled here since it is technically
 133  			// just a regular file with additional attributes.
 134  
 135  			if err := mergePAX(hdr, paxHdrs); err != nil {
 136  				return nil, err
 137  			}
 138  			if gnuLongName != "" {
 139  				hdr.Name = gnuLongName
 140  			}
 141  			if gnuLongLink != "" {
 142  				hdr.Linkname = gnuLongLink
 143  			}
 144  			if hdr.Typeflag == TypeRegA {
 145  				if bytes.HasSuffix(hdr.Name, "/") {
 146  					hdr.Typeflag = TypeDir // Legacy archives use trailing slash for directories
 147  				} else {
 148  					hdr.Typeflag = TypeReg
 149  				}
 150  			}
 151  
 152  			// The extended headers may have updated the size.
 153  			// Thus, setup the regFileReader again after merging PAX headers.
 154  			if err := tr.handleRegularFile(hdr); err != nil {
 155  				return nil, err
 156  			}
 157  
 158  			// Sparse formats rely on being able to read from the logical data
 159  			// section; there must be a preceding call to handleRegularFile.
 160  			if err := tr.handleSparseFile(hdr, rawHdr); err != nil {
 161  				return nil, err
 162  			}
 163  
 164  			// Set the final guess at the format.
 165  			if format.has(FormatUSTAR) && format.has(FormatPAX) {
 166  				format.mayOnlyBe(FormatUSTAR)
 167  			}
 168  			hdr.Format = format
 169  			return hdr, nil // This is a file, so stop
 170  		}
 171  	}
 172  }
 173  
 174  // handleRegularFile sets up the current file reader and padding such that it
 175  // can only read the following logical data section. It will properly handle
 176  // special headers that contain no data section.
 177  func (tr *Reader) handleRegularFile(hdr *Header) error {
 178  	nb := hdr.Size
 179  	if isHeaderOnlyType(hdr.Typeflag) {
 180  		nb = 0
 181  	}
 182  	if nb < 0 {
 183  		return ErrHeader
 184  	}
 185  
 186  	tr.pad = blockPadding(nb)
 187  	tr.curr = &regFileReader{r: tr.r, nb: nb}
 188  	return nil
 189  }
 190  
 191  // handleSparseFile checks if the current file is a sparse format of any type
 192  // and sets the curr reader appropriately.
 193  func (tr *Reader) handleSparseFile(hdr *Header, rawHdr *block) error {
 194  	var spd sparseDatas
 195  	var err error
 196  	if hdr.Typeflag == TypeGNUSparse {
 197  		spd, err = tr.readOldGNUSparseMap(hdr, rawHdr)
 198  	} else {
 199  		spd, err = tr.readGNUSparsePAXHeaders(hdr)
 200  	}
 201  
 202  	// If sp is non-nil, then this is a sparse file.
 203  	// Note that it is possible for len(sp) == 0.
 204  	if err == nil && spd != nil {
 205  		if isHeaderOnlyType(hdr.Typeflag) || !validateSparseEntries(spd, hdr.Size) {
 206  			return ErrHeader
 207  		}
 208  		sph := invertSparseEntries(spd, hdr.Size)
 209  		tr.curr = &sparseFileReader{tr.curr, sph, 0}
 210  	}
 211  	return err
 212  }
 213  
 214  // readGNUSparsePAXHeaders checks the PAX headers for GNU sparse headers.
 215  // If they are found, then this function reads the sparse map and returns it.
 216  // This assumes that 0.0 headers have already been converted to 0.1 headers
 217  // by the PAX header parsing logic.
 218  func (tr *Reader) readGNUSparsePAXHeaders(hdr *Header) (sparseDatas, error) {
 219  	// Identify the version of GNU headers.
 220  	var is1x0 bool
 221  	major, minor := hdr.PAXRecords[paxGNUSparseMajor], hdr.PAXRecords[paxGNUSparseMinor]
 222  	switch {
 223  	case major == "0" && (minor == "0" || minor == "1"):
 224  		is1x0 = false
 225  	case major == "1" && minor == "0":
 226  		is1x0 = true
 227  	case major != "" || minor != "":
 228  		return nil, nil // Unknown GNU sparse PAX version
 229  	case hdr.PAXRecords[paxGNUSparseMap] != "":
 230  		is1x0 = false // 0.0 and 0.1 did not have explicit version records, so guess
 231  	default:
 232  		return nil, nil // Not a PAX format GNU sparse file.
 233  	}
 234  	hdr.Format.mayOnlyBe(FormatPAX)
 235  
 236  	// Update hdr from GNU sparse PAX headers.
 237  	if name := hdr.PAXRecords[paxGNUSparseName]; name != "" {
 238  		hdr.Name = name
 239  	}
 240  	size := hdr.PAXRecords[paxGNUSparseSize]
 241  	if size == "" {
 242  		size = hdr.PAXRecords[paxGNUSparseRealSize]
 243  	}
 244  	if size != "" {
 245  		n, err := strconv.ParseInt(size, 10, 64)
 246  		if err != nil {
 247  			return nil, ErrHeader
 248  		}
 249  		hdr.Size = n
 250  	}
 251  
 252  	// Read the sparse map according to the appropriate format.
 253  	if is1x0 {
 254  		return readGNUSparseMap1x0(tr.curr)
 255  	}
 256  	return readGNUSparseMap0x1(hdr.PAXRecords)
 257  }
 258  
 259  // mergePAX merges paxHdrs into hdr for all relevant fields of Header.
 260  func mergePAX(hdr *Header, paxHdrs map[string][]byte) (err error) {
 261  	for k, v := range paxHdrs {
 262  		if v == "" {
 263  			continue // Keep the original USTAR value
 264  		}
 265  		var id64 int64
 266  		switch k {
 267  		case paxPath:
 268  			hdr.Name = v
 269  		case paxLinkpath:
 270  			hdr.Linkname = v
 271  		case paxUname:
 272  			hdr.Uname = v
 273  		case paxGname:
 274  			hdr.Gname = v
 275  		case paxUid:
 276  			id64, err = strconv.ParseInt(v, 10, 64)
 277  			hdr.Uid = int(id64) // Integer overflow possible
 278  		case paxGid:
 279  			id64, err = strconv.ParseInt(v, 10, 64)
 280  			hdr.Gid = int(id64) // Integer overflow possible
 281  		case paxAtime:
 282  			hdr.AccessTime, err = parsePAXTime(v)
 283  		case paxMtime:
 284  			hdr.ModTime, err = parsePAXTime(v)
 285  		case paxCtime:
 286  			hdr.ChangeTime, err = parsePAXTime(v)
 287  		case paxSize:
 288  			hdr.Size, err = strconv.ParseInt(v, 10, 64)
 289  		default:
 290  			if bytes.HasPrefix(k, paxSchilyXattr) {
 291  				if hdr.Xattrs == nil {
 292  					hdr.Xattrs = map[string][]byte{}
 293  				}
 294  				hdr.Xattrs[k[len(paxSchilyXattr):]] = v
 295  			}
 296  		}
 297  		if err != nil {
 298  			return ErrHeader
 299  		}
 300  	}
 301  	hdr.PAXRecords = paxHdrs
 302  	return nil
 303  }
 304  
 305  // parsePAX parses PAX headers.
 306  // If an extended header (type 'x') is invalid, ErrHeader is returned.
 307  func parsePAX(r io.Reader) (map[string][]byte, error) {
 308  	buf, err := readSpecialFile(r)
 309  	if err != nil {
 310  		return nil, err
 311  	}
 312  	sbuf := []byte(buf)
 313  
 314  	// For GNU PAX sparse format 0.0 support.
 315  	// This function transforms the sparse format 0.0 headers into format 0.1
 316  	// headers since 0.0 headers were not PAX compliant.
 317  	var sparseMap [][]byte
 318  
 319  	paxHdrs := map[string][]byte{}
 320  	for len(sbuf) > 0 {
 321  		key, value, residual, err := parsePAXRecord(sbuf)
 322  		if err != nil {
 323  			return nil, ErrHeader
 324  		}
 325  		sbuf = residual
 326  
 327  		switch key {
 328  		case paxGNUSparseOffset, paxGNUSparseNumBytes:
 329  			// Validate sparse header order and value.
 330  			if (len(sparseMap)%2 == 0 && key != paxGNUSparseOffset) ||
 331  				(len(sparseMap)%2 == 1 && key != paxGNUSparseNumBytes) ||
 332  				bytes.Contains(value, ",") {
 333  				return nil, ErrHeader
 334  			}
 335  			sparseMap = append(sparseMap, value)
 336  		default:
 337  			paxHdrs[key] = value
 338  		}
 339  	}
 340  	if len(sparseMap) > 0 {
 341  		paxHdrs[paxGNUSparseMap] = bytes.Join(sparseMap, ",")
 342  	}
 343  	return paxHdrs, nil
 344  }
 345  
 346  // readHeader reads the next block header and assumes that the underlying reader
 347  // is already aligned to a block boundary. It returns the raw block of the
 348  // header in case further processing is required.
 349  //
 350  // The err will be set to io.EOF only when one of the following occurs:
 351  //   - Exactly 0 bytes are read and EOF is hit.
 352  //   - Exactly 1 block of zeros is read and EOF is hit.
 353  //   - At least 2 blocks of zeros are read.
 354  func (tr *Reader) readHeader() (*Header, *block, error) {
 355  	// Two blocks of zero bytes marks the end of the archive.
 356  	if _, err := io.ReadFull(tr.r, tr.blk[:]); err != nil {
 357  		return nil, nil, err // EOF is okay here; exactly 0 bytes read
 358  	}
 359  	if bytes.Equal(tr.blk[:], zeroBlock[:]) {
 360  		if _, err := io.ReadFull(tr.r, tr.blk[:]); err != nil {
 361  			return nil, nil, err // EOF is okay here; exactly 1 block of zeros read
 362  		}
 363  		if bytes.Equal(tr.blk[:], zeroBlock[:]) {
 364  			return nil, nil, io.EOF // normal EOF; exactly 2 block of zeros read
 365  		}
 366  		return nil, nil, ErrHeader // Zero block and then non-zero block
 367  	}
 368  
 369  	// Verify the header matches a known format.
 370  	format := tr.blk.getFormat()
 371  	if format == FormatUnknown {
 372  		return nil, nil, ErrHeader
 373  	}
 374  
 375  	var p parser
 376  	hdr := &Header{}
 377  
 378  	// Unpack the V7 header.
 379  	v7 := tr.blk.toV7()
 380  	hdr.Typeflag = v7.typeFlag()[0]
 381  	hdr.Name = p.parseString(v7.name())
 382  	hdr.Linkname = p.parseString(v7.linkName())
 383  	hdr.Size = p.parseNumeric(v7.size())
 384  	hdr.Mode = p.parseNumeric(v7.mode())
 385  	hdr.Uid = int(p.parseNumeric(v7.uid()))
 386  	hdr.Gid = int(p.parseNumeric(v7.gid()))
 387  	hdr.ModTime = time.Unix(p.parseNumeric(v7.modTime()), 0)
 388  
 389  	// Unpack format specific fields.
 390  	if format > formatV7 {
 391  		ustar := tr.blk.toUSTAR()
 392  		hdr.Uname = p.parseString(ustar.userName())
 393  		hdr.Gname = p.parseString(ustar.groupName())
 394  		hdr.Devmajor = p.parseNumeric(ustar.devMajor())
 395  		hdr.Devminor = p.parseNumeric(ustar.devMinor())
 396  
 397  		var prefix []byte
 398  		switch {
 399  		case format.has(FormatUSTAR | FormatPAX):
 400  			hdr.Format = format
 401  			ustar := tr.blk.toUSTAR()
 402  			prefix = p.parseString(ustar.prefix())
 403  
 404  			// For Format detection, check if block is properly formatted since
 405  			// the parser is more liberal than what USTAR actually permits.
 406  			notASCII := func(r rune) bool { return r >= 0x80 }
 407  			if bytes.IndexFunc(tr.blk[:], notASCII) >= 0 {
 408  				hdr.Format = FormatUnknown // Non-ASCII characters in block.
 409  			}
 410  			nul := func(b []byte) bool { return int(b[len(b)-1]) == 0 }
 411  			if !(nul(v7.size()) && nul(v7.mode()) && nul(v7.uid()) && nul(v7.gid()) &&
 412  				nul(v7.modTime()) && nul(ustar.devMajor()) && nul(ustar.devMinor())) {
 413  				hdr.Format = FormatUnknown // Numeric fields must end in NUL
 414  			}
 415  		case format.has(formatSTAR):
 416  			star := tr.blk.toSTAR()
 417  			prefix = p.parseString(star.prefix())
 418  			hdr.AccessTime = time.Unix(p.parseNumeric(star.accessTime()), 0)
 419  			hdr.ChangeTime = time.Unix(p.parseNumeric(star.changeTime()), 0)
 420  		case format.has(FormatGNU):
 421  			hdr.Format = format
 422  			var p2 parser
 423  			gnu := tr.blk.toGNU()
 424  			if b := gnu.accessTime(); b[0] != 0 {
 425  				hdr.AccessTime = time.Unix(p2.parseNumeric(b), 0)
 426  			}
 427  			if b := gnu.changeTime(); b[0] != 0 {
 428  				hdr.ChangeTime = time.Unix(p2.parseNumeric(b), 0)
 429  			}
 430  
 431  			// Prior to Go1.8, the Writer had a bug where it would output
 432  			// an invalid tar file in certain rare situations because the logic
 433  			// incorrectly believed that the old GNU format had a prefix field.
 434  			// This is wrong and leads to an output file that mangles the
 435  			// atime and ctime fields, which are often left unused.
 436  			//
 437  			// In order to continue reading tar files created by former, buggy
 438  			// versions of Go, we skeptically parse the atime and ctime fields.
 439  			// If we are unable to parse them and the prefix field looks like
 440  			// an ASCII string, then we fallback on the pre-Go1.8 behavior
 441  			// of treating these fields as the USTAR prefix field.
 442  			//
 443  			// Note that this will not use the fallback logic for all possible
 444  			// files generated by a pre-Go1.8 toolchain. If the generated file
 445  			// happened to have a prefix field that parses as valid
 446  			// atime and ctime fields (e.g., when they are valid octal strings),
 447  			// then it is impossible to distinguish between a valid GNU file
 448  			// and an invalid pre-Go1.8 file.
 449  			//
 450  			// See https://golang.org/issues/12594
 451  			// See https://golang.org/issues/21005
 452  			if p2.err != nil {
 453  				hdr.AccessTime, hdr.ChangeTime = time.Time{}, time.Time{}
 454  				ustar := tr.blk.toUSTAR()
 455  				if s := p.parseString(ustar.prefix()); isASCII(s) {
 456  					prefix = s
 457  				}
 458  				hdr.Format = FormatUnknown // Buggy file is not GNU
 459  			}
 460  		}
 461  		if len(prefix) > 0 {
 462  			hdr.Name = prefix + "/" + hdr.Name
 463  		}
 464  	}
 465  	return hdr, &tr.blk, p.err
 466  }
 467  
 468  // readOldGNUSparseMap reads the sparse map from the old GNU sparse format.
 469  // The sparse map is stored in the tar header if it's small enough.
 470  // If it's larger than four entries, then one or more extension headers are used
 471  // to store the rest of the sparse map.
 472  //
 473  // The Header.Size does not reflect the size of any extended headers used.
 474  // Thus, this function will read from the raw io.Reader to fetch extra headers.
 475  // This method mutates blk in the process.
 476  func (tr *Reader) readOldGNUSparseMap(hdr *Header, blk *block) (sparseDatas, error) {
 477  	// Make sure that the input format is GNU.
 478  	// Unfortunately, the STAR format also has a sparse header format that uses
 479  	// the same type flag but has a completely different layout.
 480  	if blk.getFormat() != FormatGNU {
 481  		return nil, ErrHeader
 482  	}
 483  	hdr.Format.mayOnlyBe(FormatGNU)
 484  
 485  	var p parser
 486  	hdr.Size = p.parseNumeric(blk.toGNU().realSize())
 487  	if p.err != nil {
 488  		return nil, p.err
 489  	}
 490  	s := blk.toGNU().sparse()
 491  	spd := make(sparseDatas, 0, s.maxEntries())
 492  	for {
 493  		for i := 0; i < s.maxEntries(); i++ {
 494  			// This termination condition is identical to GNU and BSD tar.
 495  			if s.entry(i).offset()[0] == 0x00 {
 496  				break // Don't return, need to process extended headers (even if empty)
 497  			}
 498  			offset := p.parseNumeric(s.entry(i).offset())
 499  			length := p.parseNumeric(s.entry(i).length())
 500  			if p.err != nil {
 501  				return nil, p.err
 502  			}
 503  			spd = append(spd, sparseEntry{Offset: offset, Length: length})
 504  		}
 505  
 506  		if s.isExtended()[0] > 0 {
 507  			// There are more entries. Read an extension header and parse its entries.
 508  			if _, err := mustReadFull(tr.r, blk[:]); err != nil {
 509  				return nil, err
 510  			}
 511  			s = blk.toSparse()
 512  			continue
 513  		}
 514  		return spd, nil // Done
 515  	}
 516  }
 517  
 518  // readGNUSparseMap1x0 reads the sparse map as stored in GNU's PAX sparse format
 519  // version 1.0. The format of the sparse map consists of a series of
 520  // newline-terminated numeric fields. The first field is the number of entries
 521  // and is always present. Following this are the entries, consisting of two
 522  // fields (offset, length). This function must stop reading at the end
 523  // boundary of the block containing the last newline.
 524  //
 525  // Note that the GNU manual says that numeric values should be encoded in octal
 526  // format. However, the GNU tar utility itself outputs these values in decimal.
 527  // As such, this library treats values as being encoded in decimal.
 528  func readGNUSparseMap1x0(r io.Reader) (sparseDatas, error) {
 529  	var (
 530  		cntNewline int64
 531  		buf        bytes.Buffer
 532  		blk        block
 533  		totalSize  int
 534  	)
 535  
 536  	// feedTokens copies data in blocks from r into buf until there are
 537  	// at least cnt newlines in buf. It will not read more blocks than needed.
 538  	feedTokens := func(n int64) error {
 539  		for cntNewline < n {
 540  			totalSize += len(blk)
 541  			if totalSize > maxSpecialFileSize {
 542  				return errSparseTooLong
 543  			}
 544  			if _, err := mustReadFull(r, blk[:]); err != nil {
 545  				return err
 546  			}
 547  			buf.Write(blk[:])
 548  			for _, c := range blk {
 549  				if c == '\n' {
 550  					cntNewline++
 551  				}
 552  			}
 553  		}
 554  		return nil
 555  	}
 556  
 557  	// nextToken gets the next token delimited by a newline. This assumes that
 558  	// at least one newline exists in the buffer.
 559  	nextToken := func() []byte {
 560  		cntNewline--
 561  		tok, _ := buf.ReadString('\n')
 562  		return bytes.TrimRight(tok, "\n")
 563  	}
 564  
 565  	// Parse for the number of entries.
 566  	// Use integer overflow resistant math to check this.
 567  	if err := feedTokens(1); err != nil {
 568  		return nil, err
 569  	}
 570  	numEntries, err := strconv.ParseInt(nextToken(), 10, 0) // Intentionally parse as native int
 571  	if err != nil || numEntries < 0 || int(2*numEntries) < int(numEntries) {
 572  		return nil, ErrHeader
 573  	}
 574  
 575  	// Parse for all member entries.
 576  	// numEntries is trusted after this since feedTokens limits the number of
 577  	// tokens based on maxSpecialFileSize.
 578  	if err := feedTokens(2 * numEntries); err != nil {
 579  		return nil, err
 580  	}
 581  	spd := make(sparseDatas, 0, numEntries)
 582  	for i := int64(0); i < numEntries; i++ {
 583  		offset, err1 := strconv.ParseInt(nextToken(), 10, 64)
 584  		length, err2 := strconv.ParseInt(nextToken(), 10, 64)
 585  		if err1 != nil || err2 != nil {
 586  			return nil, ErrHeader
 587  		}
 588  		spd = append(spd, sparseEntry{Offset: offset, Length: length})
 589  	}
 590  	return spd, nil
 591  }
 592  
 593  // readGNUSparseMap0x1 reads the sparse map as stored in GNU's PAX sparse format
 594  // version 0.1. The sparse map is stored in the PAX headers.
 595  func readGNUSparseMap0x1(paxHdrs map[string][]byte) (sparseDatas, error) {
 596  	// Get number of entries.
 597  	// Use integer overflow resistant math to check this.
 598  	numEntriesStr := paxHdrs[paxGNUSparseNumBlocks]
 599  	numEntries, err := strconv.ParseInt(numEntriesStr, 10, 0) // Intentionally parse as native int
 600  	if err != nil || numEntries < 0 || int(2*numEntries) < int(numEntries) {
 601  		return nil, ErrHeader
 602  	}
 603  
 604  	// There should be two numbers in sparseMap for each entry.
 605  	sparseMap := bytes.Split(paxHdrs[paxGNUSparseMap], ",")
 606  	if len(sparseMap) == 1 && sparseMap[0] == "" {
 607  		sparseMap = sparseMap[:0]
 608  	}
 609  	if int64(len(sparseMap)) != 2*numEntries {
 610  		return nil, ErrHeader
 611  	}
 612  
 613  	// Loop through the entries in the sparse map.
 614  	// numEntries is trusted now.
 615  	spd := make(sparseDatas, 0, numEntries)
 616  	for len(sparseMap) >= 2 {
 617  		offset, err1 := strconv.ParseInt(sparseMap[0], 10, 64)
 618  		length, err2 := strconv.ParseInt(sparseMap[1], 10, 64)
 619  		if err1 != nil || err2 != nil {
 620  			return nil, ErrHeader
 621  		}
 622  		spd = append(spd, sparseEntry{Offset: offset, Length: length})
 623  		sparseMap = sparseMap[2:]
 624  	}
 625  	return spd, nil
 626  }
 627  
 628  // Read reads from the current file in the tar archive.
 629  // It returns (0, io.EOF) when it reaches the end of that file,
 630  // until [Next] is called to advance to the next file.
 631  //
 632  // If the current file is sparse, then the regions marked as a hole
 633  // are read back as NUL-bytes.
 634  //
 635  // Calling Read on special types like [TypeLink], [TypeSymlink], [TypeChar],
 636  // [TypeBlock], [TypeDir], and [TypeFifo] returns (0, [io.EOF]) regardless of what
 637  // the [Header.Size] claims.
 638  func (tr *Reader) Read(b []byte) (int, error) {
 639  	if tr.err != nil {
 640  		return 0, tr.err
 641  	}
 642  	n, err := tr.curr.Read(b)
 643  	if err != nil && err != io.EOF {
 644  		tr.err = err
 645  	}
 646  	return n, err
 647  }
 648  
 649  // writeTo writes the content of the current file to w.
 650  // The bytes written matches the number of remaining bytes in the current file.
 651  //
 652  // If the current file is sparse and w is an io.WriteSeeker,
 653  // then writeTo uses Seek to skip past holes defined in Header.SparseHoles,
 654  // assuming that skipped regions are filled with NULs.
 655  // This always writes the last byte to ensure w is the right size.
 656  //
 657  // TODO(dsnet): Re-export this when adding sparse file support.
 658  // See https://golang.org/issue/22735
 659  func (tr *Reader) writeTo(w io.Writer) (int64, error) {
 660  	if tr.err != nil {
 661  		return 0, tr.err
 662  	}
 663  	n, err := tr.curr.WriteTo(w)
 664  	if err != nil {
 665  		tr.err = err
 666  	}
 667  	return n, err
 668  }
 669  
 670  // regFileReader is a fileReader for reading data from a regular file entry.
 671  type regFileReader struct {
 672  	r  io.Reader // Underlying Reader
 673  	nb int64     // Number of remaining bytes to read
 674  }
 675  
 676  func (fr *regFileReader) Read(b []byte) (n int, err error) {
 677  	if int64(len(b)) > fr.nb {
 678  		b = b[:fr.nb]
 679  	}
 680  	if len(b) > 0 {
 681  		n, err = fr.r.Read(b)
 682  		fr.nb -= int64(n)
 683  	}
 684  	switch {
 685  	case err == io.EOF && fr.nb > 0:
 686  		return n, io.ErrUnexpectedEOF
 687  	case err == nil && fr.nb == 0:
 688  		return n, io.EOF
 689  	default:
 690  		return n, err
 691  	}
 692  }
 693  
 694  func (fr *regFileReader) WriteTo(w io.Writer) (int64, error) {
 695  	return io.Copy(w, struct{ io.Reader }{fr})
 696  }
 697  
 698  // logicalRemaining implements fileState.logicalRemaining.
 699  func (fr regFileReader) logicalRemaining() int64 {
 700  	return fr.nb
 701  }
 702  
 703  // physicalRemaining implements fileState.physicalRemaining.
 704  func (fr regFileReader) physicalRemaining() int64 {
 705  	return fr.nb
 706  }
 707  
 708  // sparseFileReader is a fileReader for reading data from a sparse file entry.
 709  type sparseFileReader struct {
 710  	fr  fileReader  // Underlying fileReader
 711  	sp  sparseHoles // Normalized list of sparse holes
 712  	pos int64       // Current position in sparse file
 713  }
 714  
 715  func (sr *sparseFileReader) Read(b []byte) (n int, err error) {
 716  	finished := int64(len(b)) >= sr.logicalRemaining()
 717  	if finished {
 718  		b = b[:sr.logicalRemaining()]
 719  	}
 720  
 721  	b0 := b
 722  	endPos := sr.pos + int64(len(b))
 723  	for endPos > sr.pos && err == nil {
 724  		var nf int // Bytes read in fragment
 725  		holeStart, holeEnd := sr.sp[0].Offset, sr.sp[0].endOffset()
 726  		if sr.pos < holeStart { // In a data fragment
 727  			bf := b[:min(int64(len(b)), holeStart-sr.pos)]
 728  			nf, err = tryReadFull(sr.fr, bf)
 729  		} else { // In a hole fragment
 730  			bf := b[:min(int64(len(b)), holeEnd-sr.pos)]
 731  			nf, err = tryReadFull(zeroReader{}, bf)
 732  		}
 733  		b = b[nf:]
 734  		sr.pos += int64(nf)
 735  		if sr.pos >= holeEnd && len(sr.sp) > 1 {
 736  			sr.sp = sr.sp[1:] // Ensure last fragment always remains
 737  		}
 738  	}
 739  
 740  	n = len(b0) - len(b)
 741  	switch {
 742  	case err == io.EOF:
 743  		return n, errMissData // Less data in dense file than sparse file
 744  	case err != nil:
 745  		return n, err
 746  	case sr.logicalRemaining() == 0 && sr.physicalRemaining() > 0:
 747  		return n, errUnrefData // More data in dense file than sparse file
 748  	case finished:
 749  		return n, io.EOF
 750  	default:
 751  		return n, nil
 752  	}
 753  }
 754  
 755  func (sr *sparseFileReader) WriteTo(w io.Writer) (n int64, err error) {
 756  	ws, ok := w.(io.WriteSeeker)
 757  	if ok {
 758  		if _, err := ws.Seek(0, io.SeekCurrent); err != nil {
 759  			ok = false // Not all io.Seeker can really seek
 760  		}
 761  	}
 762  	if !ok {
 763  		return io.Copy(w, struct{ io.Reader }{sr})
 764  	}
 765  
 766  	var writeLastByte bool
 767  	pos0 := sr.pos
 768  	for sr.logicalRemaining() > 0 && !writeLastByte && err == nil {
 769  		var nf int64 // Size of fragment
 770  		holeStart, holeEnd := sr.sp[0].Offset, sr.sp[0].endOffset()
 771  		if sr.pos < holeStart { // In a data fragment
 772  			nf = holeStart - sr.pos
 773  			nf, err = io.CopyN(ws, sr.fr, nf)
 774  		} else { // In a hole fragment
 775  			nf = holeEnd - sr.pos
 776  			if sr.physicalRemaining() == 0 {
 777  				writeLastByte = true
 778  				nf--
 779  			}
 780  			_, err = ws.Seek(nf, io.SeekCurrent)
 781  		}
 782  		sr.pos += nf
 783  		if sr.pos >= holeEnd && len(sr.sp) > 1 {
 784  			sr.sp = sr.sp[1:] // Ensure last fragment always remains
 785  		}
 786  	}
 787  
 788  	// If the last fragment is a hole, then seek to 1-byte before EOF, and
 789  	// write a single byte to ensure the file is the right size.
 790  	if writeLastByte && err == nil {
 791  		_, err = ws.Write([]byte{0})
 792  		sr.pos++
 793  	}
 794  
 795  	n = sr.pos - pos0
 796  	switch {
 797  	case err == io.EOF:
 798  		return n, errMissData // Less data in dense file than sparse file
 799  	case err != nil:
 800  		return n, err
 801  	case sr.logicalRemaining() == 0 && sr.physicalRemaining() > 0:
 802  		return n, errUnrefData // More data in dense file than sparse file
 803  	default:
 804  		return n, nil
 805  	}
 806  }
 807  
 808  func (sr sparseFileReader) logicalRemaining() int64 {
 809  	return sr.sp[len(sr.sp)-1].endOffset() - sr.pos
 810  }
 811  func (sr sparseFileReader) physicalRemaining() int64 {
 812  	return sr.fr.physicalRemaining()
 813  }
 814  
 815  type zeroReader struct{}
 816  
 817  func (zeroReader) Read(b []byte) (int, error) {
 818  	clear(b)
 819  	return len(b), nil
 820  }
 821  
 822  // mustReadFull is like io.ReadFull except it returns
 823  // io.ErrUnexpectedEOF when io.EOF is hit before len(b) bytes are read.
 824  func mustReadFull(r io.Reader, b []byte) (int, error) {
 825  	n, err := tryReadFull(r, b)
 826  	if err == io.EOF {
 827  		err = io.ErrUnexpectedEOF
 828  	}
 829  	return n, err
 830  }
 831  
 832  // tryReadFull is like io.ReadFull except it returns
 833  // io.EOF when it is hit before len(b) bytes are read.
 834  func tryReadFull(r io.Reader, b []byte) (n int, err error) {
 835  	for len(b) > n && err == nil {
 836  		var nn int
 837  		nn, err = r.Read(b[n:])
 838  		n += nn
 839  	}
 840  	if len(b) == n && err == io.EOF {
 841  		err = nil
 842  	}
 843  	return n, err
 844  }
 845  
 846  // readSpecialFile is like io.ReadAll except it returns
 847  // ErrFieldTooLong if more than maxSpecialFileSize is read.
 848  func readSpecialFile(r io.Reader) ([]byte, error) {
 849  	buf, err := io.ReadAll(io.LimitReader(r, maxSpecialFileSize+1))
 850  	if len(buf) > maxSpecialFileSize {
 851  		return nil, ErrFieldTooLong
 852  	}
 853  	return buf, err
 854  }
 855  
 856  // discard skips n bytes in r, reporting an error if unable to do so.
 857  func discard(r io.Reader, n int64) error {
 858  	// If possible, Seek to the last byte before the end of the data section.
 859  	// Do this because Seek is often lazy about reporting errors; this will mask
 860  	// the fact that the stream may be truncated. We can rely on the
 861  	// io.CopyN done shortly afterwards to trigger any IO errors.
 862  	var seekSkipped int64 // Number of bytes skipped via Seek
 863  	if sr, ok := r.(io.Seeker); ok && n > 1 {
 864  		// Not all io.Seeker can actually Seek. For example, os.Stdin implements
 865  		// io.Seeker, but calling Seek always returns an error and performs
 866  		// no action. Thus, we try an innocent seek to the current position
 867  		// to see if Seek is really supported.
 868  		pos1, err := sr.Seek(0, io.SeekCurrent)
 869  		if pos1 >= 0 && err == nil {
 870  			// Seek seems supported, so perform the real Seek.
 871  			pos2, err := sr.Seek(n-1, io.SeekCurrent)
 872  			if pos2 < 0 || err != nil {
 873  				return err
 874  			}
 875  			seekSkipped = pos2 - pos1
 876  		}
 877  	}
 878  
 879  	copySkipped, err := io.CopyN(io.Discard, r, n-seekSkipped)
 880  	if err == io.EOF && seekSkipped+copySkipped < n {
 881  		err = io.ErrUnexpectedEOF
 882  	}
 883  	return err
 884  }
 885