From 2aefaf33c514f6bcd909eb4dd49084ff7e623fb6 Mon Sep 17 00:00:00 2001 From: Nicolas Ramz Date: Mon, 20 Apr 2020 14:59:30 +0200 Subject: [PATCH] fix: readdir should check for access rights, fixes #294 --- lib/binding.js | 2 ++ test/lib/fs.readdir.spec.js | 45 ++++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/binding.js b/lib/binding.js index 9215ad5f..9dbcb9c1 100644 --- a/lib/binding.js +++ b/lib/binding.js @@ -954,6 +954,8 @@ Binding.prototype.readdir = function( throw new FSError('ENOTDIR', dirpath); } + this.access(dirpath, parseInt('0002', 8)); + let list = dir.list(); if (encoding === 'buffer') { list = list.map(function(item) { diff --git a/test/lib/fs.readdir.spec.js b/test/lib/fs.readdir.spec.js index ed8c299f..0dbe2153 100644 --- a/test/lib/fs.readdir.spec.js +++ b/test/lib/fs.readdir.spec.js @@ -21,7 +21,15 @@ describe('fs.readdir(path, callback)', function() { empty: {} } } - } + }, + denied: mock.directory({ + mode: 0o000, + items: [ + { + 'one.txt': 'content' + } + ] + }) }); }); afterEach(mock.restore); @@ -83,6 +91,29 @@ describe('fs.readdir(path, callback)', function() { ); }); + it('calls with an error for restricted path', function(done) { + fs.readdir('denied', function(err, items) { + assert.instanceOf(err, Error); + assert.isUndefined(items); + done(); + }); + }); + + withPromise.it('promise calls with an error for restricted path', function( + done + ) { + fs.promises.readdir('denied').then( + function() { + assert.fail('should not succeed.'); + done(); + }, + function(err) { + assert.instanceOf(err, Error); + done(); + } + ); + }); + inVersion('>=10.10').it('should support "withFileTypes" option', function( done ) { @@ -207,4 +238,16 @@ describe('fs.readdirSync(path)', function() { fs.readdirSync('bogus'); }); }); + + it('throws when access refused', function() { + assert.throws(function() { + fs.readdirSync('denied'); + }); + }); + + it('throws when access refused', function() { + assert.throws(function() { + fs.readdirSync('denied'); + }); + }); });