diff --git a/lib/mkdirs/__tests__/README.md b/lib/mkdirs/__tests__/README.md deleted file mode 100644 index a211103b..00000000 --- a/lib/mkdirs/__tests__/README.md +++ /dev/null @@ -1 +0,0 @@ -These tests imported from https://github.com/substack/node-mkdirp. \ No newline at end of file diff --git a/lib/mkdirs/__tests__/issue-209.test.js b/lib/mkdirs/__tests__/issue-209.test.js new file mode 100644 index 00000000..2640eb92 --- /dev/null +++ b/lib/mkdirs/__tests__/issue-209.test.js @@ -0,0 +1,38 @@ +var assert = require('assert') +var fse = require(process.cwd()) + +/* global describe, it */ + +describe('mkdirp: issue-209, win32, when bad path, should return a cleaner error', function () { + // only seems to be an issue on Windows. + if (process.platform !== 'win32') return + + it('should return a callback', function (done) { + var file = './bad?dir' + fse.mkdirp(file, function (err) { + assert(err, 'error is present') + assert.strictEqual(err.code, 'EINVAL') + + var file2 = 'c:\\tmp\foo:moo' + fse.mkdirp(file2, function (err) { + assert(err, 'error is present') + assert.strictEqual(err.code, 'EINVAL') + done() + }) + }) + }) + + describe('> sync', function () { + it('should throw an error', function () { + var didErr + try { + var file = 'c:\\tmp\foo:moo' + fse.mkdirpSync(file) + } catch (err) { + // console.error(err) + didErr = true + } + assert(didErr) + }) + }) +}) diff --git a/lib/mkdirs/mkdirs-sync.js b/lib/mkdirs/mkdirs-sync.js index 138d56ce..3f30680d 100644 --- a/lib/mkdirs/mkdirs-sync.js +++ b/lib/mkdirs/mkdirs-sync.js @@ -1,5 +1,6 @@ var fs = require('graceful-fs') var path = require('path') +var invalidWin32Path = require('./win32').invalidWin32Path var o777 = parseInt('0777', 8) @@ -11,6 +12,12 @@ function mkdirsSync (p, opts, made) { var mode = opts.mode var xfs = opts.fs || fs + if (process.platform === 'win32' && invalidWin32Path(p)) { + var errInval = new Error(p + ' contains invalid WIN32 path characters.') + errInval.code = 'EINVAL' + throw errInval + } + if (mode === undefined) { mode = o777 & (~process.umask()) } diff --git a/lib/mkdirs/mkdirs.js b/lib/mkdirs/mkdirs.js index 2bdfa041..939776c4 100644 --- a/lib/mkdirs/mkdirs.js +++ b/lib/mkdirs/mkdirs.js @@ -1,5 +1,6 @@ var fs = require('graceful-fs') var path = require('path') +var invalidWin32Path = require('./win32').invalidWin32Path var o777 = parseInt('0777', 8) @@ -11,6 +12,12 @@ function mkdirs (p, opts, callback, made) { opts = { mode: opts } } + if (process.platform === 'win32' && invalidWin32Path(p)) { + var errInval = new Error(p + ' contains invalid WIN32 path characters.') + errInval.code = 'EINVAL' + return callback(errInval) + } + var mode = opts.mode var xfs = opts.fs || fs diff --git a/lib/mkdirs/win32.js b/lib/mkdirs/win32.js new file mode 100644 index 00000000..569ac1ae --- /dev/null +++ b/lib/mkdirs/win32.js @@ -0,0 +1,24 @@ +'use strict' +var path = require('path') + +// get drive on windows +function getRootPath (p) { + p = path.normalize(path.resolve(p)).split(path.sep) + if (p.length > 0) return p[0] + else return null +} + +// http://stackoverflow.com/a/62888/10333 contains more accurate +// TODO: expand to include the rest +var INVALID_PATH_CHARS = /[<>:"|?*]/ + +function invalidWin32Path (p) { + var rp = getRootPath(p) + p = p.replace(rp, '') + return INVALID_PATH_CHARS.test(p) +} + +module.exports = { + getRootPath: getRootPath, + invalidWin32Path: invalidWin32Path +}