# All files / tar/lib read-entry.js

100% Statements 53/53
100% Branches 36/36
100% Functions 3/3
100% Lines 51/51

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    11x
    11x

    11x
    11x

    4004x
    4004x
    4004x
    4004x
    4004x
    4004x
    4004x
    4004x
    4004x
    4004x
    4004x

    3241x

    760x
    760x

    3x

    4004x
    4004x
    4004x
    3720x
    4004x
    4004x
    4004x
    4004x
    4004x
    4004x
    4004x
    4004x
    4004x
    4004x
    4004x

    4004x
    4004x

    2222x
    2222x
    2x

    2220x
    2220x
    2220x
    2220x
    2220x
    673x

    1547x
    132x

    1415x

    457x

    6384x

    2657x

     'use strict'
    const types = require('./types.js')
    const MiniPass = require('minipass')

    const SLURP = Symbol('slurp')
    module.exports = class ReadEntry extends MiniPass {
      constructor (header, ex, gex) {
        super()
        this.extended = ex
        this.globalExtended = gex
        this.header = header
        this.startBlockSize = 512 * Math.ceil(header.size / 512)
        this.blockRemain = this.startBlockSize
        this.remain = header.size
        this.type = header.type
        this.meta = false
        this.ignore = false
        switch (this.type) {
          case 'File':
          case 'OldFile':
          case 'Link':
          case 'SymbolicLink':
          case 'CharacterDevice':
          case 'BlockDevice':
          case 'Directory':
          case 'FIFO':
          case 'ContiguousFile':
          case 'GNUDumpDir':
            break

          case 'NextFileHasLongLinkpath':
          case 'NextFileHasLongPath':
          case 'OldGnuLongPath':
          case 'GlobalExtendedHeader':
          case 'ExtendedHeader':
          case 'OldExtendedHeader':
            this.meta = true
            break

          // NOTE: gnutar and bsdtar treat unrecognized types as 'File'
          // it may be worth doing the same, but with a warning.
          default:
            this.ignore = true
        }

        this.path = header.path
        this.mode = header.mode
        if (this.mode)
          this.mode = this.mode & 0o7777
        this.uid = header.uid
        this.gid = header.gid
        this.uname = header.uname
        this.gname = header.gname
        this.size = header.size
        this.mtime = header.mtime
        this.atime = header.atime
        this.ctime = header.ctime
        this.linkpath = header.linkpath
        this.uname = header.uname
        this.gname = header.gname

        if (ex) this[SLURP](ex)
        if (gex) this[SLURP](gex, true)
      }

      write (data) {
        const writeLen = data.length
        if (writeLen > this.blockRemain)
          throw new Error('writing more to entry than is appropriate')

        const r = this.remain
        const br = this.blockRemain
        this.remain = Math.max(0, r - writeLen)
        this.blockRemain = Math.max(0, br - writeLen)
        if (this.ignore)
          return true

        if (r >= writeLen)
          return super.write(data)

        // r < writeLen
        return super.write(data.slice(0, r))
      }

      [SLURP] (ex, global) {
        for (let k in ex) {
          // we slurp in everything except for the path attribute in
          // a global extended header, because that's weird.
          if (ex[k] !== null && ex[k] !== undefined &&
              !(global && k === 'path'))
            this[k] = ex[k]
        }
      }
    }