Skip to content

Commit

Permalink
CARNET-3; Fix broken symlink handling; <cargo>Fix broken symlink hand…
Browse files Browse the repository at this point in the history
…ling</cargo>

Root cause isaacs/rimraf#65
Root cause ember-cli/ember-cli#3413
Root cause Rich-Harris/sander#1
Fix #170
  • Loading branch information
isaacs authored and billsedison committed Jun 23, 2019
1 parent 18c75d8 commit 5ac2403
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 5 deletions.
19 changes: 15 additions & 4 deletions glob.js
Expand Up @@ -627,12 +627,23 @@ Glob.prototype._stat = function (f, cb) {
}

var self = this
var statcb = inflight('stat\0' + abs, statcb_)
var statcb = inflight('stat\0' + abs, lstatcb_)
if (statcb)
fs.stat(abs, statcb)
fs.lstat(abs, statcb)

function statcb_ (er, stat) {
self._stat2(f, abs, er, stat, cb)
function lstatcb_ (er, lstat) {
if (lstat && lstat.isSymbolicLink()) {
// If it's a symlink, then treat it as the target, unless
// the target does not exist, then treat it as a file.
return fs.stat(abs, function (er, stat) {
if (er)
self._stat2(f, abs, null, lstat, cb)
else
self._stat2(f, abs, er, stat, cb)
})
} else {
self._stat2(f, abs, er, lstat, cb)
}
}
}

Expand Down
13 changes: 12 additions & 1 deletion sync.js
Expand Up @@ -391,11 +391,22 @@ GlobSync.prototype._stat = function (f) {
var exists
var stat = this.statCache[abs]
if (!stat) {
var lstat
try {
stat = fs.statSync(abs)
lstat = fs.lstatSync(abs)
} catch (er) {
return false
}

if (lstat.isSymbolicLink()) {
try {
stat = fs.statSync(abs)
} catch (er) {
stat = lstat
}
} else {
stat = lstat
}
}

this.statCache[abs] = stat
Expand Down
1 change: 1 addition & 0 deletions test/bash-results.json
Expand Up @@ -95,6 +95,7 @@
"./test/abort.js",
"./test/bash-comparison.js",
"./test/bash-results.json",
"./test/broken-symlink.js",
"./test/cwd-test.js",
"./test/empty-set.js",
"./test/error-callback.js",
Expand Down
78 changes: 78 additions & 0 deletions test/broken-symlink.js
@@ -0,0 +1,78 @@
var fs = require('fs')
var test = require('tap').test
var glob = require('../')
var mkdirp = require('mkdirp')

process.chdir(__dirname)

var link = 'a/broken-link/link'

var patterns = [
'a/broken-link/*',
'a/broken-link/**',
'a/broken-link/**/link',
'a/broken-link/**/*',
'a/broken-link/link',
'a/broken-link/{link,asdf}',
'a/broken-link/+(link|asdf)',
'a/broken-link/!(asdf)'
]

var opts = [
null,
{ nonull: true },
{ mark: true },
{ stat: true }
]

test('set up broken symlink', function (t) {
cleanup()
mkdirp.sync('a/broken-link')
fs.symlinkSync('this-does-not-exist', 'a/broken-link/link')
t.end()
})

test('async test', function (t) {
var count = patterns.length * opts.length
t.plan(patterns.length)
patterns.forEach(function (pattern) {
t.test(pattern, function (t) {
t.plan(opts.length)

opts.forEach(function (opt) {
glob(pattern, opt, cb(opt))
})

function cb (opt) { return function (er, res) {
if (er)
throw er
var msg = pattern + ' ' + JSON.stringify(opt)
t.notEqual(res.indexOf(link), -1, msg)
}}
})
})
})

test('sync test', function (t) {
t.plan(patterns.length)
patterns.forEach(function (pattern) {
t.test(pattern, function (t) {
t.plan(opts.length)

opts.forEach(function (opt) {
var res = glob.sync(pattern, opt)
t.notEqual(res.indexOf(link), -1, 'opt=' + JSON.stringify(opt))
})
})
})
})

test('cleanup', function (t) {
cleanup()
t.end()
})

function cleanup () {
try { fs.unlinkSync('a/broken-link/link') } catch (e) {}
try { fs.rmdirSync('a/broken-link') } catch (e) {}
}

0 comments on commit 5ac2403

Please sign in to comment.