Skip to content

Commit 7f1b31e

Browse files
committed
patched v6.0.5
1 parent 7251efb commit 7f1b31e

20 files changed

+728
-77
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
language: node_js
22

33
node_js:
4-
- node
4+
- '14'
55
- 12
66
- 10

lib/mkdir.js

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const mkdirp = require('mkdirp')
88
const fs = require('fs')
99
const path = require('path')
1010
const chownr = require('chownr')
11+
const normPath = require('./normalize-windows-path.js')
1112

1213
class SymlinkError extends Error {
1314
constructor (symlink, path) {
@@ -33,7 +34,11 @@ class CwdError extends Error {
3334
}
3435
}
3536

36-
const mkdir = module.exports = (dir, opt, cb) => {
37+
const cGet = (cache, key) => cache.get(normPath(key))
38+
const cSet = (cache, key, val) => cache.set(normPath(key), val)
39+
40+
module.exports = (dir, opt, cb) => {
41+
dir = normPath(dir)
3742
// if there's any overlap between mask and mode,
3843
// then we'll need an explicit chmod
3944
const umask = opt.umask
@@ -44,18 +49,18 @@ const mkdir = module.exports = (dir, opt, cb) => {
4449
const gid = opt.gid
4550
const doChown = typeof uid === 'number' &&
4651
typeof gid === 'number' &&
47-
( uid !== opt.processUid || gid !== opt.processGid )
52+
(uid !== opt.processUid || gid !== opt.processGid)
4853

4954
const preserve = opt.preserve
5055
const unlink = opt.unlink
5156
const cache = opt.cache
52-
const cwd = opt.cwd
57+
const cwd = normPath(opt.cwd)
5358

5459
const done = (er, created) => {
5560
if (er)
5661
cb(er)
5762
else {
58-
cache.set(dir, true)
63+
cSet(cache, dir, true)
5964
if (created && doChown)
6065
chownr(created, uid, gid, er => done(er))
6166
else if (needChmod)
@@ -65,21 +70,22 @@ const mkdir = module.exports = (dir, opt, cb) => {
6570
}
6671
}
6772

68-
if (cache && cache.get(dir) === true)
73+
if (cache && cGet(cache, dir) === true)
6974
return done()
7075

71-
if (dir === cwd)
76+
if (dir === cwd) {
7277
return fs.stat(dir, (er, st) => {
7378
if (er || !st.isDirectory())
7479
er = new CwdError(dir, er && er.code || 'ENOTDIR')
7580
done(er)
7681
})
82+
}
7783

7884
if (preserve)
7985
return mkdirp(dir, {mode}).then(made => done(null, made), done)
8086

8187
const sub = path.relative(cwd, dir)
82-
const parts = sub.split(/\/|\\/)
88+
const parts = sub.split('/')
8389
mkdir_(cwd, parts, mode, cache, unlink, cwd, null, done)
8490
}
8591

@@ -88,7 +94,7 @@ const mkdir_ = (base, parts, mode, cache, unlink, cwd, created, cb) => {
8894
return cb(null, created)
8995
const p = parts.shift()
9096
const part = base + '/' + p
91-
if (cache.get(part))
97+
if (cGet(cache, part))
9298
return mkdir_(part, parts, mode, cache, unlink, cwd, created, cb)
9399
fs.mkdir(part, mode, onmkdir(part, parts, mode, cache, unlink, cwd, created, cb))
94100
}
@@ -104,13 +110,13 @@ const onmkdir = (part, parts, mode, cache, unlink, cwd, created, cb) => er => {
104110
cb(statEr)
105111
else if (st.isDirectory())
106112
mkdir_(part, parts, mode, cache, unlink, cwd, created, cb)
107-
else if (unlink)
113+
else if (unlink) {
108114
fs.unlink(part, er => {
109115
if (er)
110116
return cb(er)
111117
fs.mkdir(part, mode, onmkdir(part, parts, mode, cache, unlink, cwd, created, cb))
112118
})
113-
else if (st.isSymbolicLink())
119+
} else if (st.isSymbolicLink())
114120
return cb(new SymlinkError(part, part + '/' + parts.join('/')))
115121
else
116122
cb(er)
@@ -121,7 +127,8 @@ const onmkdir = (part, parts, mode, cache, unlink, cwd, created, cb) => er => {
121127
}
122128
}
123129

124-
const mkdirSync = module.exports.sync = (dir, opt) => {
130+
module.exports.sync = (dir, opt) => {
131+
dir = normPath(dir)
125132
// if there's any overlap between mask and mode,
126133
// then we'll need an explicit chmod
127134
const umask = opt.umask
@@ -132,22 +139,22 @@ const mkdirSync = module.exports.sync = (dir, opt) => {
132139
const gid = opt.gid
133140
const doChown = typeof uid === 'number' &&
134141
typeof gid === 'number' &&
135-
( uid !== opt.processUid || gid !== opt.processGid )
142+
(uid !== opt.processUid || gid !== opt.processGid)
136143

137144
const preserve = opt.preserve
138145
const unlink = opt.unlink
139146
const cache = opt.cache
140-
const cwd = opt.cwd
147+
const cwd = normPath(opt.cwd)
141148

142149
const done = (created) => {
143-
cache.set(dir, true)
150+
cSet(cache, dir, true)
144151
if (created && doChown)
145152
chownr.sync(created, uid, gid)
146153
if (needChmod)
147154
fs.chmodSync(dir, mode)
148155
}
149156

150-
if (cache && cache.get(dir) === true)
157+
if (cache && cGet(cache, dir) === true)
151158
return done()
152159

153160
if (dir === cwd) {
@@ -169,33 +176,32 @@ const mkdirSync = module.exports.sync = (dir, opt) => {
169176
return done(mkdirp.sync(dir, mode))
170177

171178
const sub = path.relative(cwd, dir)
172-
const parts = sub.split(/\/|\\/)
179+
const parts = sub.split('/')
173180
let created = null
174181
for (let p = parts.shift(), part = cwd;
175-
p && (part += '/' + p);
176-
p = parts.shift()) {
177-
178-
if (cache.get(part))
182+
p && (part += '/' + p);
183+
p = parts.shift()) {
184+
if (cGet(cache, part))
179185
continue
180186

181187
try {
182188
fs.mkdirSync(part, mode)
183189
created = created || part
184-
cache.set(part, true)
190+
cSet(cache, part, true)
185191
} catch (er) {
186192
if (er.path && path.dirname(er.path) === cwd &&
187193
(er.code === 'ENOTDIR' || er.code === 'ENOENT'))
188194
return new CwdError(cwd, er.code)
189195

190196
const st = fs.lstatSync(part)
191197
if (st.isDirectory()) {
192-
cache.set(part, true)
198+
cSet(cache, part, true)
193199
continue
194200
} else if (unlink) {
195201
fs.unlinkSync(part)
196202
fs.mkdirSync(part, mode)
197203
created = created || part
198-
cache.set(part, true)
204+
cSet(cache, part, true)
199205
continue
200206
} else if (st.isSymbolicLink())
201207
return new SymlinkError(part, part + '/' + parts.join('/'))

lib/normalize-windows-path.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// on windows, either \ or / are valid directory separators.
2+
// on unix, \ is a valid character in filenames.
3+
// so, on windows, and only on windows, we replace all \ chars with /,
4+
// so that we can use / as our one and only directory separator char.
5+
6+
const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform
7+
module.exports = platform !== 'win32' ? p => p
8+
: p => p.replace(/\\/g, '/')

lib/pack.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ const ONDRAIN = Symbol('ondrain')
5454
const fs = require('fs')
5555
const path = require('path')
5656
const warner = require('./warn-mixin.js')
57+
const normPath = require('./normalize-windows-path.js')
58+
const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform
5759

5860
const Pack = warner(class Pack extends MiniPass {
5961
constructor (opt) {
@@ -66,7 +68,7 @@ const Pack = warner(class Pack extends MiniPass {
6668
this.preservePaths = !!opt.preservePaths
6769
this.strict = !!opt.strict
6870
this.noPax = !!opt.noPax
69-
this.prefix = (opt.prefix || '').replace(/(\\|\/)+$/, '')
71+
this.prefix = normPath(opt.prefix || '').replace(/\/+$/, '')
7072
this.linkCache = opt.linkCache || new Map()
7173
this.statCache = opt.statCache || new Map()
7274
this.readdirCache = opt.readdirCache || new Map()
@@ -133,7 +135,7 @@ const Pack = warner(class Pack extends MiniPass {
133135
}
134136

135137
[ADDTARENTRY] (p) {
136-
const absolute = path.resolve(this.cwd, p.path)
138+
const absolute = normPath(path.resolve(this.cwd, p.path))
137139
if (this.prefix)
138140
p.path = this.prefix + '/' + p.path.replace(/^\.(\/+|$)/, '')
139141

@@ -152,9 +154,10 @@ const Pack = warner(class Pack extends MiniPass {
152154
}
153155

154156
[ADDFSENTRY] (p) {
155-
const absolute = path.resolve(this.cwd, p)
156-
if (this.prefix)
157+
const absolute = normPath(path.resolve(this.cwd, p))
158+
if (this.prefix){
157159
p = this.prefix + '/' + p.replace(/^\.(\/+|$)/, '')
160+
}
158161

159162
this[QUEUE].push(new PackJob(p, absolute))
160163
this[PROCESS]()

lib/path-reservations.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// while still allowing maximal safe parallelization.
88

99
const assert = require('assert')
10+
const normPath = require('./normalize-windows-path.js')
1011

1112
module.exports = () => {
1213
// path => [function or Set]
@@ -20,8 +21,9 @@ module.exports = () => {
2021
// return a set of parent dirs for a given path
2122
const { join } = require('path')
2223
const getDirs = path =>
23-
join(path).split(/[\\\/]/).slice(0, -1).reduce((set, path) =>
24-
set.length ? set.concat(join(set[set.length-1], path)) : [path], [])
24+
normPath(join(path)).split('/').slice(0, -1).reduce((set, path) =>
25+
set.length ? set.concat(normPath(join(set[set.length - 1], path)))
26+
: [path], [])
2527

2628
// functions currently running
2729
const running = new Set()

lib/strip-absolute-path.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// unix absolute paths are also absolute on win32, so we use this for both
2+
const { isAbsolute, parse } = require('path').win32
3+
4+
// returns [root, stripped]
5+
module.exports = path => {
6+
let r = ''
7+
let parsed = parse(path)
8+
while (isAbsolute(path) || parsed.root) {
9+
// windows will think that //x/y/z has a "root" of //x/y/
10+
const root = path.charAt(0) === '/' && path.slice(0, 4) !== '//?/' ? '/' : parsed.root
11+
path = path.substr(root.length)
12+
r += root
13+
parsed = parse(path)
14+
}
15+
return [r, path]
16+
}

lib/strip-trailing-slashes.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// this is the only approach that was significantly faster than using
2+
// str.replace(/\/+$/, '') for strings ending with a lot of / chars and
3+
// containing multiple / chars.
4+
const batchStrings = [
5+
'/'.repeat(1024),
6+
'/'.repeat(512),
7+
'/'.repeat(256),
8+
'/'.repeat(128),
9+
'/'.repeat(64),
10+
'/'.repeat(32),
11+
'/'.repeat(16),
12+
'/'.repeat(8),
13+
'/'.repeat(4),
14+
'/'.repeat(2),
15+
'/',
16+
]
17+
18+
module.exports = str => {
19+
for (const s of batchStrings) {
20+
while (str.length >= s.length && str.slice(-1 * s.length) === s)
21+
str = str.slice(0, -1 * s.length)
22+
}
23+
return str
24+
}

0 commit comments

Comments
 (0)