Make path.extname do the right thing when the last path component is . or ..
authorBert Belder <bertbelder@gmail.com>
Wed, 18 Jan 2012 14:09:42 +0000 (15:09 +0100)
committerBert Belder <bertbelder@gmail.com>
Wed, 18 Jan 2012 14:21:58 +0000 (15:21 +0100)
Closes GH-2526

lib/path.js
test/simple/test-path.js

index b70225b1d6215d5eb930b5beb0893ea1a233f606..c10ff7efce5f28c72a86cd9e4449a933311b3740 100644 (file)
@@ -61,7 +61,7 @@ if (isWindows) {
       /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?([\s\S]*?)$/;
 
   // Regex to split the tail part of the above into [*, dir, basename, ext]
-  var splitTailRe = /^([\s\S]+[\\\/](?!$)|[\\\/])?((?:[\s\S]+?)?(\.[^.]*)?)$/;
+  var splitTailRe = /^([\s\S]+[\\\/](?!$)|[\\\/])?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/\\]*)?)$/;
 
   // Function to split a filename into [root, dir, basename, ext]
   // windows version
@@ -255,7 +255,7 @@ if (isWindows) {
 
   // Split a filename into [root, dir, basename, ext], unix version
   // 'root' is just a slash, or nothing.
-  var splitPathRe = /^(\/?)([\s\S]+\/(?!$)|\/)?((?:[\s\S]+?)?(\.[^.]*)?)$/;
+  var splitPathRe = /^(\/?)([\s\S]+\/(?!$)|\/)?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/]*)?)$/;
   var splitPath = function(filename) {
     var result = splitPathRe.exec(filename);
     return [result[1] || '', result[2] || '', result[3] || '', result[4] || ''];
index 1ee78dad68fe761b1725fc72d24541220be80217..92c2647fd2671da1c80f8538f292ff108e1170b9 100644 (file)
@@ -102,6 +102,34 @@ assert.equal(path.extname('/.file.ext'), '.ext');
 assert.equal(path.extname('.path/file.ext'), '.ext');
 assert.equal(path.extname('file.ext.ext'), '.ext');
 assert.equal(path.extname('file.'), '.');
+assert.equal(path.extname('.'), '');
+assert.equal(path.extname('./'), '');
+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('..'), '');
+assert.equal(path.extname('../'), '');
+assert.equal(path.extname('..file.ext'), '.ext');
+assert.equal(path.extname('..file'), '.file');
+assert.equal(path.extname('..file.'), '.');
+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/'), '');
+
+if (isWindows) {
+  // On windows, backspace is a path separator.
+  assert.equal(path.extname('.\\'), '');
+  assert.equal(path.extname('..\\'), '');
+  assert.equal(path.extname('file.ext\\'), '');
+} 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\\');
+}
 
 // path.join tests
 var failures = [];