Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.

Commit

Permalink
Merge pull request #6041 from adobe/iwehrman/normalize-UNC-paths
Browse files Browse the repository at this point in the history
Correctly normalize UNC paths
  • Loading branch information
gruehle committed Nov 19, 2013
2 parents cdf1416 + a49cc5f commit 9a1fe2e
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 18 deletions.
3 changes: 0 additions & 3 deletions src/brackets.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,6 @@ define(function (require, exports, module) {
require("file/NativeFileError");

PerfUtils.addMeasurement("brackets module dependencies resolved");

// Initialize the file system
FileSystem.init(require("fileSystemImpl"));

// Local variables
var params = new UrlParams();
Expand Down
30 changes: 23 additions & 7 deletions src/filesystem/FileSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,21 +388,29 @@ define(function (require, exports, module) {
return (fullPath[0] === "/" || fullPath[1] === ":");
};

/*
* Matches continguous groups of forward slashes
* @const
*/
var _DUPLICATED_SLASH_RE = /\/{2,}/g;

/**
* Returns a canonical version of the path: no duplicated "/"es, no ".."s,
* and directories guaranteed to end in a trailing "/"
* @param {!string} path Absolute path, using "/" as path separator
* @param {boolean=} isDirectory
* @return {!string}
*/
function _normalizePath(path, isDirectory) {
FileSystem.prototype._normalizePath = function (path, isDirectory) {

if (!FileSystem.isAbsolutePath(path)) {
throw new Error("Paths must be absolute: '" + path + "'"); // expect only absolute paths
}


var isUNCPath = this._impl.normalizeUNCPaths && path.search(_DUPLICATED_SLASH_RE) === 0;

// Remove duplicated "/"es
path = path.replace(/\/{2,}/g, "/");
path = path.replace(_DUPLICATED_SLASH_RE, "/");

// Remove ".." segments
if (path.indexOf("..") !== -1) {
Expand All @@ -427,8 +435,13 @@ define(function (require, exports, module) {
}
}

if (isUNCPath) {
// Restore the leading double slash that was removed previously
path = "/" + path;
}

return path;
}
};

/**
* Return a File object for the specified path.
Expand All @@ -438,7 +451,7 @@ define(function (require, exports, module) {
* @return {File} The File object. This file may not yet exist on disk.
*/
FileSystem.prototype.getFileForPath = function (path) {
path = _normalizePath(path, false);
path = this._normalizePath(path, false);
var file = this._index.getEntry(path);

if (!file) {
Expand All @@ -457,7 +470,7 @@ define(function (require, exports, module) {
* @return {Directory} The Directory object. This directory may not yet exist on disk.
*/
FileSystem.prototype.getDirectoryForPath = function (path) {
path = _normalizePath(path, true);
path = this._normalizePath(path, true);
var directory = this._index.getEntry(path);

if (!directory) {
Expand Down Expand Up @@ -579,7 +592,7 @@ define(function (require, exports, module) {
return;
}

path = _normalizePath(path, false);
path = this._normalizePath(path, false);
var entry = this._index.getEntry(path);

if (entry) {
Expand Down Expand Up @@ -800,4 +813,7 @@ define(function (require, exports, module) {

// Create the singleton instance
_instance = new FileSystem();

// Initialize the singleton instance
_instance.init(require("fileSystemImpl"));
});
3 changes: 3 additions & 0 deletions src/filesystem/impls/appshell/AppshellFileSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -419,4 +419,7 @@ define(function (require, exports, module) {
exports.watchPath = watchPath;
exports.unwatchPath = unwatchPath;
exports.unwatchAll = unwatchAll;

// Only perform UNC path normalization on Windows
exports.normalizeUNCPaths = appshell.platform === "win";
});
14 changes: 6 additions & 8 deletions test/SpecRunner.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@
require.config({
baseUrl: "../src",
paths: {
"test" : "../test",
"perf" : "../test/perf",
"spec" : "../test/spec",
"text" : "thirdparty/text/text",
"i18n" : "thirdparty/i18n/i18n"
"test" : "../test",
"perf" : "../test/perf",
"spec" : "../test/spec",
"text" : "thirdparty/text/text",
"i18n" : "thirdparty/i18n/i18n",
"fileSystemImpl" : "filesystem/impls/appshell/AppshellFileSystem"
}
});

Expand Down Expand Up @@ -92,9 +93,6 @@ define(function (require, exports, module) {
* for the installer in this run of Brackets.
*/
var NODE_CONNECTION_TIMEOUT = 30000; // 30 seconds - TODO: share with StaticServer?

// Initialize the file system
FileSystem.init(require("filesystem/impls/appshell/AppshellFileSystem"));

// parse URL parameters
params.parse();
Expand Down
52 changes: 52 additions & 0 deletions test/spec/FileSystem-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,58 @@ define(function (require, exports, module) {
});

it("should eliminate duplicated (contiguous) slashes", function () {
MockFileSystemImpl.normalizeUNCPaths = false;
testPrefixes(["", "c:"], function () {
expectNormDir("/", "/");
expectNormDir("//", "/");
expectNormDir("///", "/");
expectNormDir("//foo", "/foo/");
expectNormDir("/foo//", "/foo/");
expectNormDir("//foo//", "/foo/");
expectNormDir("///foo///", "/foo/");
expectNormDir("/foo//bar", "/foo/bar/");
expectNormDir("/foo///bar", "/foo/bar/");

expectNormFile("/foo", "/foo");
expectNormFile("//foo", "/foo");
expectNormFile("///foo", "/foo");
expectNormFile("/foo//bar", "/foo/bar");
expectNormFile("/foo///bar", "/foo/bar");
expectNormFile("//foo///bar", "/foo/bar");
expectNormFile("///foo///bar", "/foo/bar");
expectNormFile("///foo//bar", "/foo/bar");
expectNormFile("///foo/bar", "/foo/bar");
});
});

it("should normalize continguous-slash prefixes for UNC paths", function () {
// UNC paths should have leading slashes reduced to a single leading pair
MockFileSystemImpl.normalizeUNCPaths = true;
testPrefixes([""], function () {
expectNormDir("/", "/");
expectNormDir("//", "//");
expectNormDir("///", "//");
expectNormDir("//foo", "//foo/");
expectNormDir("/foo//", "/foo/");
expectNormDir("//foo//", "//foo/");
expectNormDir("///foo///", "//foo/");
expectNormDir("/foo//bar", "/foo/bar/");
expectNormDir("/foo///bar", "/foo/bar/");

expectNormFile("/foo", "/foo");
expectNormFile("//foo", "//foo");
expectNormFile("///foo", "//foo");
expectNormFile("/foo//bar", "/foo/bar");
expectNormFile("/foo///bar", "/foo/bar");
expectNormFile("//foo///bar", "//foo/bar");
expectNormFile("///foo///bar", "//foo/bar");
expectNormFile("///foo//bar", "//foo/bar");
expectNormFile("///foo/bar", "//foo/bar");
});

// UNC paths do not begin with a letter, so normalization is unchanged
testPrefixes(["c:"], function () {
expectNormDir("/", "/");
expectNormDir("//", "/");
expectNormDir("///", "/");
expectNormDir("//foo", "/foo/");
Expand All @@ -151,6 +202,7 @@ define(function (require, exports, module) {
expectNormDir("/foo//bar", "/foo/bar/");
expectNormDir("/foo///bar", "/foo/bar/");

expectNormFile("/foo", "/foo");
expectNormFile("//foo", "/foo");
expectNormFile("///foo", "/foo");
expectNormFile("/foo//bar", "/foo/bar");
Expand Down
7 changes: 7 additions & 0 deletions test/spec/MockFileSystemImpl.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ define(function (require, exports, module) {
}
};

// Indicates whether, by default, the FS should perform UNC Path normalization
var _normalizeUNCPathsDefault = false;

// "Live" data for this instance of the file system. Use reset() to
// initialize with _initialData
var _data;
Expand Down Expand Up @@ -339,11 +342,15 @@ define(function (require, exports, module) {
exports.unwatchPath = unwatchPath;
exports.unwatchAll = unwatchAll;

exports.normalizeUNCPaths = _normalizeUNCPathsDefault;

// Test methods
exports.reset = function () {
_data = {};
$.extend(_data, _initialData);
_hooks = {};

exports.normalizeUNCPaths = _normalizeUNCPathsDefault;
};

/**
Expand Down

0 comments on commit 9a1fe2e

Please sign in to comment.