From 6a91eab0970a87431743c79ecb8e3efaed1796d9 Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Fri, 11 Jan 2013 18:42:46 +0100 Subject: [PATCH] path: make basename and extname ignore trailing slashes Fixes #4536 --- lib/path.js | 13 ++++++------ test/simple/test-path.js | 45 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/lib/path.js b/lib/path.js index 0b24de299fc..7970ed130b5 100644 --- a/lib/path.js +++ b/lib/path.js @@ -63,7 +63,7 @@ if (isWindows) { // Regex to split the tail part of the above into [*, dir, basename, ext] var splitTailRe = - /^([\s\S]+[\\\/](?!$)|[\\\/])?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/\\]*)?)$/; + /^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/; // Function to split a filename into [root, dir, basename, ext] // windows version @@ -74,9 +74,9 @@ if (isWindows) { tail = result[3] || ''; // Split the tail into dir, basename and extension var result2 = splitTailRe.exec(tail), - dir = result2[1] || '', - basename = result2[2] || '', - ext = result2[3] || ''; + dir = result2[1], + basename = result2[2], + ext = result2[3]; return [device, dir, basename, ext]; }; @@ -289,10 +289,9 @@ if (isWindows) { // Split a filename into [root, dir, basename, ext], unix version // 'root' is just a slash, or nothing. var splitPathRe = - /^(\/?)([\s\S]+\/(?!$)|\/)?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/]*)?)$/; + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; var splitPath = function(filename) { - var result = splitPathRe.exec(filename); - return [result[1] || '', result[2] || '', result[3] || '', result[4] || '']; + return splitPathRe.exec(filename).slice(1); }; // path.resolve([from ...], to) diff --git a/test/simple/test-path.js b/test/simple/test-path.js index 1c03887e14a..cb75fc8e505 100644 --- a/test/simple/test-path.js +++ b/test/simple/test-path.js @@ -30,6 +30,29 @@ var f = __filename; assert.equal(path.basename(f), 'test-path.js'); assert.equal(path.basename(f, '.js'), 'test-path'); +assert.equal(path.basename(''), ''); +assert.equal(path.basename('/dir/basename.ext'), 'basename.ext'); +assert.equal(path.basename('/basename.ext'), 'basename.ext'); +assert.equal(path.basename('basename.ext'), 'basename.ext'); +assert.equal(path.basename('basename.ext/'), 'basename.ext'); +assert.equal(path.basename('basename.ext//'), 'basename.ext'); + +if (isWindows) { + // On Windows a backslash acts as a path separator. + assert.equal(path.basename('\\dir\\basename.ext'), 'basename.ext'); + assert.equal(path.basename('\\basename.ext'), 'basename.ext'); + assert.equal(path.basename('basename.ext'), 'basename.ext'); + assert.equal(path.basename('basename.ext\\'), 'basename.ext'); + assert.equal(path.basename('basename.ext\\\\'), 'basename.ext'); + +} else { + // On unix a backslash is just treated as any other character. + assert.equal(path.basename('\\dir\\basename.ext'), '\\dir\\basename.ext'); + assert.equal(path.basename('\\basename.ext'), '\\basename.ext'); + assert.equal(path.basename('basename.ext'), 'basename.ext'); + assert.equal(path.basename('basename.ext\\'), 'basename.ext\\'); + assert.equal(path.basename('basename.ext\\\\'), 'basename.ext\\\\'); +} // POSIX filenames may include control characters // c.f. http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html @@ -46,7 +69,9 @@ assert.equal(path.dirname(f).substr(-11), assert.equal(path.dirname('/a/b/'), '/a'); assert.equal(path.dirname('/a/b'), '/a'); assert.equal(path.dirname('/a'), '/'); +assert.equal(path.dirname(''), '.'); assert.equal(path.dirname('/'), '/'); +assert.equal(path.dirname('////'), '/'); if (isWindows) { assert.equal(path.dirname('c:\\'), 'c:\\'); @@ -114,18 +139,34 @@ assert.equal(path.extname('..file..'), '.'); assert.equal(path.extname('...'), '.'); assert.equal(path.extname('...ext'), '.ext'); assert.equal(path.extname('....'), '.'); -assert.equal(path.extname('file.ext/'), ''); +assert.equal(path.extname('file.ext/'), '.ext'); +assert.equal(path.extname('file.ext//'), '.ext'); +assert.equal(path.extname('file/'), ''); +assert.equal(path.extname('file//'), ''); +assert.equal(path.extname('file./'), '.'); +assert.equal(path.extname('file.//'), '.'); if (isWindows) { // On windows, backspace is a path separator. assert.equal(path.extname('.\\'), ''); assert.equal(path.extname('..\\'), ''); - assert.equal(path.extname('file.ext\\'), ''); + assert.equal(path.extname('file.ext\\'), '.ext'); + assert.equal(path.extname('file.ext\\\\'), '.ext'); + assert.equal(path.extname('file\\'), ''); + assert.equal(path.extname('file\\\\'), ''); + assert.equal(path.extname('file.\\'), '.'); + assert.equal(path.extname('file.\\\\'), '.'); + } else { // On unix, backspace is a valid name component like any other character. assert.equal(path.extname('.\\'), ''); assert.equal(path.extname('..\\'), '.\\'); assert.equal(path.extname('file.ext\\'), '.ext\\'); + assert.equal(path.extname('file.ext\\\\'), '.ext\\\\'); + assert.equal(path.extname('file\\'), ''); + assert.equal(path.extname('file\\\\'), ''); + assert.equal(path.extname('file.\\'), '.\\'); + assert.equal(path.extname('file.\\\\'), '.\\\\'); } // path.join tests