diff --git a/src/filesystem/implementation.js b/src/filesystem/implementation.js index f80acf3..e050076 100644 --- a/src/filesystem/implementation.js +++ b/src/filesystem/implementation.js @@ -1691,7 +1691,7 @@ function readFile(fs, context, path, options, callback) { var flags = validate_flags(options.flag || 'r'); if(!flags) { - callback(new Errors.EINVAL('flags is not valid')); + return callback(new Errors.EINVAL('flags is not valid')); } open_file(context, path, flags, function(err, fileNode) { @@ -1701,21 +1701,34 @@ function readFile(fs, context, path, options, callback) { var ofd = new OpenFileDescription(path, fileNode.id, flags, 0); var fd = fs.allocDescriptor(ofd); - fstat_file(context, ofd, function(err2, fstatResult) { - if(err2) { - return callback(err2); + function cleanup() { + fs.releaseDescriptor(fd); + ofd = null; + } + + fstat_file(context, ofd, function(err, fstatResult) { + if(err) { + cleanup(); + return callback(err); } var stats = new Stats(fstatResult, fs.name); + + if(stats.isDirectory()) { + cleanup(); + return callback(new Errors.EISDIR('illegal operation on directory')); + } + var size = stats.size; var buffer = new Buffer(size); buffer.fill(0); - read_data(context, ofd, buffer, 0, size, 0, function(err3, nbytes) { - if(err3) { - return callback(err3); + read_data(context, ofd, buffer, 0, size, 0, function(err, nbytes) { + cleanup(); + + if(err) { + return callback(err); } - fs.releaseDescriptor(fd); var data; if(options.encoding === 'utf8') { diff --git a/tests/bugs/issue254.js b/tests/bugs/issue254.js new file mode 100644 index 0000000..95f4a5f --- /dev/null +++ b/tests/bugs/issue254.js @@ -0,0 +1,47 @@ +var Filer = require('../..'); +var util = require('../lib/test-utils.js'); +var expect = require('chai').expect; + +describe('EISDIR when trying to open a dir path - issue 254', function() { + beforeEach(util.setup); + afterEach(util.cleanup); + + it('should fail with EISDIR for root dir', function(done) { + var fs = util.fs(); + + fs.readFile('/', function(err) { + expect(err.code).to.equal('EISDIR'); + done(); + }); + }); + + it('should fail with EISDIR for regular dir', function(done) { + var fs = util.fs(); + + fs.mkdir('/dir', function(err) { + if(err) throw err; + + fs.readFile('/dir', function(err) { + expect(err.code).to.equal('EISDIR'); + done(); + }); + }); + }); + + it('should fail with EISDIR for symlinked dir', function(done) { + var fs = util.fs(); + + fs.mkdir('/dir', function(err) { + if(err) throw err; + + fs.symlink('/dir', '/link', function(err) { + if(err) throw err; + + fs.readFile('/link', function(err) { + expect(err.code).to.equal('EISDIR'); + done(); + }); + }); + }); + }); +}); diff --git a/tests/index.js b/tests/index.js index 5d9632a..c0684ff 100644 --- a/tests/index.js +++ b/tests/index.js @@ -71,3 +71,5 @@ require("./bugs/issue239"); require("./bugs/issue249"); require("./bugs/ls-depth-bug"); require("./bugs/issue247.js"); +require("./bugs/issue254.js"); +