Comparing version
@@ -135,2 +135,8 @@ // Load modules | ||
// Propagate non-directory errors | ||
if (err.output.statusCode !== 403 || err.data !== 'EISDIR') { | ||
return reply(err); | ||
} | ||
// Directory | ||
@@ -137,0 +143,0 @@ |
@@ -205,3 +205,3 @@ // Load modules | ||
Fs.open(path, mode, function(err, fd) { | ||
Fs.open(path, mode, function (err, fd) { | ||
@@ -214,13 +214,17 @@ if (err) { | ||
if (err.code === 'EACCES' || err.code === 'EPERM') { | ||
return callback(Boom.forbidden(null, err.code)); | ||
} | ||
if (path.indexOf('\u0000') !== -1) { // handle "Path must be a string without null bytes" error | ||
return callback(Boom.forbidden()); | ||
} | ||
return callback(Boom.wrap(err, null, 'failed to open file')); | ||
return callback(Boom.wrap(err, null, 'Failed to open file')); | ||
} | ||
Fs.fstat(fd, function(err, stat) { | ||
Fs.fstat(fd, function (err, stat) { | ||
if (err) { | ||
Fs.close(fd, Hoek.ignore); | ||
return callback(Boom.wrap(err, null, 'failed to stat file')); | ||
return callback(Boom.wrap(err, null, 'Failed to stat file')); | ||
} | ||
@@ -230,3 +234,3 @@ | ||
Fs.close(fd, Hoek.ignore); | ||
return callback(Boom.forbidden()); | ||
return callback(Boom.forbidden(null, 'EISDIR')); | ||
} | ||
@@ -233,0 +237,0 @@ |
{ | ||
"name": "inert", | ||
"description": "Static file and directory handlers plugin for hapi.js", | ||
"version": "2.1.1", | ||
"version": "2.1.2", | ||
"repository": "git://github.com/hapijs/inert", | ||
@@ -6,0 +6,0 @@ "main": "index", |
// Load modules | ||
var Fs = require('fs'); | ||
var Os = require('os'); | ||
var Path = require('path'); | ||
@@ -752,3 +753,66 @@ var Boom = require('boom'); | ||
}); | ||
it('returns a 403 when missing file read permission', function (done) { | ||
var filename = Hoek.uniqueFilename(Os.tmpDir()); | ||
Fs.writeFileSync(filename, 'data'); | ||
var fd; | ||
if (process.platform === 'win32') { | ||
// make a permissionless file by unlinking an open file | ||
fd = Fs.openSync(filename, 'r'); | ||
Fs.unlinkSync(filename); | ||
} else { | ||
Fs.chmodSync(filename, 0); | ||
} | ||
var server = provisionServer(); | ||
server.route({ method: 'GET', path: '/test/{path*}', handler: { directory: { path: Path.dirname(filename) } } }); | ||
server.inject('/test/' + Path.basename(filename), function (res) { | ||
// cleanup | ||
if (typeof fd === 'number') { | ||
Fs.closeSync(fd); | ||
} else { | ||
Fs.unlinkSync(filename); | ||
} | ||
expect(res.statusCode).to.equal(403); | ||
done(); | ||
}); | ||
}); | ||
it('returns error when a file open fails', function (done) { | ||
var orig = Fs.open; | ||
Fs.open = function () { // can return EMFILE error | ||
Fs.open = orig; | ||
var callback = arguments[arguments.length - 1]; | ||
callback(new Error('failed')); | ||
}; | ||
var server = provisionServer(); | ||
server.route({ method: 'GET', path: '/test/{path*}', handler: { directory: { path: './' } } }); | ||
server.inject('/test/fail', function (res) { | ||
expect(res.statusCode).to.equal(500); | ||
done(); | ||
}); | ||
}); | ||
it('returns a 403 for null byte paths', function (done) { | ||
var server = provisionServer(); | ||
server.route({ method: 'GET', path: '/{path*}', handler: { directory: { path: './' } } }); | ||
server.inject('/index%00.html', function (res) { | ||
expect(res.statusCode).to.equal(403); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |
365994
0.69%1797
3.1%