mirror of https://github.com/lukechilds/node.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
4.4 KiB
163 lines
4.4 KiB
var test = require('tap').test
|
|
var assert = require('assert')
|
|
var path = require('path')
|
|
var requireInject = require('require-inject')
|
|
var cache_dir = path.resolve(__dirname, 'correct-mkdir')
|
|
|
|
test('correct-mkdir: no race conditions', function (t) {
|
|
var mock_fs = {}
|
|
var did_hook = false
|
|
mock_fs.stat = function (path, cb) {
|
|
if (path === cache_dir) {
|
|
// Return a non-matching owner
|
|
cb(null, {
|
|
uid: +process.uid + 1,
|
|
isDirectory: function () {
|
|
return true
|
|
}
|
|
})
|
|
if (!did_hook) {
|
|
did_hook = true
|
|
doHook()
|
|
}
|
|
} else {
|
|
assert.ok(false, 'Unhandled stat path: ' + path)
|
|
}
|
|
}
|
|
var chown_in_progress = 0
|
|
var mock_chownr = function (path, uid, gid, cb) {
|
|
++chown_in_progress
|
|
process.nextTick(function () {
|
|
--chown_in_progress
|
|
cb(null)
|
|
})
|
|
}
|
|
var mocks = {
|
|
'graceful-fs': mock_fs,
|
|
'chownr': mock_chownr
|
|
}
|
|
var correctMkdir = requireInject('../../lib/utils/correct-mkdir.js', mocks)
|
|
|
|
var calls_in_progress = 3
|
|
function handleCallFinish () {
|
|
t.equal(chown_in_progress, 0, 'should not return while chown still in progress')
|
|
if (!--calls_in_progress) {
|
|
t.end()
|
|
}
|
|
}
|
|
function doHook () {
|
|
// This is fired during the first correctMkdir call, after the stat has finished
|
|
// but before the chownr has finished
|
|
// Buggy old code will fail and return a cached value before initial call is done
|
|
correctMkdir(cache_dir, handleCallFinish)
|
|
}
|
|
// Initial call
|
|
correctMkdir(cache_dir, handleCallFinish)
|
|
// Immediate call again in case of race condition there
|
|
correctMkdir(cache_dir, handleCallFinish)
|
|
})
|
|
|
|
test('correct-mkdir: ignore ENOENTs from chownr', function (t) {
|
|
var mock_fs = {}
|
|
mock_fs.stat = function (path, cb) {
|
|
if (path === cache_dir) {
|
|
cb(null, {
|
|
isDirectory: function () {
|
|
return true
|
|
}
|
|
})
|
|
} else {
|
|
assert.ok(false, 'Unhandled stat path: ' + path)
|
|
}
|
|
}
|
|
var mock_chownr = function (path, uid, gid, cb) {
|
|
cb({code: 'ENOENT'})
|
|
}
|
|
var mocks = {
|
|
'graceful-fs': mock_fs,
|
|
'chownr': mock_chownr
|
|
}
|
|
var correctMkdir = requireInject('../../lib/utils/correct-mkdir.js', mocks)
|
|
|
|
function handleCallFinish (err) {
|
|
t.ifErr(err, 'chownr\'s ENOENT errors were ignored')
|
|
t.end()
|
|
}
|
|
correctMkdir(cache_dir, handleCallFinish)
|
|
})
|
|
|
|
// NEED TO RUN LAST
|
|
|
|
// These test checks that Windows users are protected by crashes related to
|
|
// unexpectedly having a UID/GID other than 0 if a user happens to add these
|
|
// variables to their environment. There are assumptions in correct-mkdir
|
|
// that special-case Windows by checking on UID-related things.
|
|
test('correct-mkdir: SUDO_UID and SUDO_GID non-Windows', function (t) {
|
|
process.env.SUDO_UID = 999
|
|
process.env.SUDO_GID = 999
|
|
process.getuid = function () { return 0 }
|
|
process.getgid = function () { return 0 }
|
|
var mock_fs = {}
|
|
mock_fs.stat = function (path, cb) {
|
|
if (path === cache_dir) {
|
|
cb(null, {
|
|
uid: 0,
|
|
isDirectory: function () {
|
|
return true
|
|
}
|
|
})
|
|
} else {
|
|
assert.ok(false, 'Unhandled stat path: ' + path)
|
|
}
|
|
}
|
|
var mock_chownr = function (path, uid, gid, cb) {
|
|
t.is(uid, +process.env.SUDO_UID, 'using the environment\'s UID')
|
|
t.is(gid, +process.env.SUDO_GID, 'using the environment\'s GID')
|
|
cb(null, {})
|
|
}
|
|
var mocks = {
|
|
'graceful-fs': mock_fs,
|
|
'chownr': mock_chownr
|
|
}
|
|
var correctMkdir = requireInject('../../lib/utils/correct-mkdir.js', mocks)
|
|
|
|
function handleCallFinish () {
|
|
t.end()
|
|
}
|
|
correctMkdir(cache_dir, handleCallFinish)
|
|
})
|
|
|
|
test('correct-mkdir: SUDO_UID and SUDO_GID Windows', function (t) {
|
|
process.env.SUDO_UID = 999
|
|
process.env.SUDO_GID = 999
|
|
delete process.getuid
|
|
delete process.getgid
|
|
var mock_fs = {}
|
|
mock_fs.stat = function (path, cb) {
|
|
if (path === cache_dir) {
|
|
cb(null, {
|
|
uid: 0,
|
|
isDirectory: function () {
|
|
return true
|
|
}
|
|
})
|
|
} else {
|
|
assert.ok(false, 'Unhandled stat path: ' + path)
|
|
}
|
|
}
|
|
var mock_chownr = function (path, uid, gid, cb) {
|
|
t.fail('chownr should not be called at all on Windows')
|
|
cb('nope')
|
|
}
|
|
var mocks = {
|
|
'graceful-fs': mock_fs,
|
|
'chownr': mock_chownr
|
|
}
|
|
var correctMkdir = requireInject('../../lib/utils/correct-mkdir.js', mocks)
|
|
|
|
function handleCallFinish (err) {
|
|
t.ifErr(err, 'chownr was not called because Windows')
|
|
t.end()
|
|
}
|
|
correctMkdir(cache_dir, handleCallFinish)
|
|
})
|
|
|