Skip to content

Commit

Permalink
[FIX] LibraryFormatter: Fix handling of paths containing special char…
Browse files Browse the repository at this point in the history
…acters

FS paths containing characters which can be interpreted as regular
expression metacharacters may lead to issues during the namespace
detection of libraries.

Alternatively we could switch to using
https://www.npmjs.com/package/escape-string-regexp which we already use
elsewhere. But I think this case here can be kept simple.

Fixes SAP/ui5-tooling#526
  • Loading branch information
RandomByte committed Jul 1, 2021
1 parent 9414096 commit 2093562
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 16 deletions.
31 changes: 17 additions & 14 deletions lib/types/library/LibraryFormatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,26 +270,29 @@ class LibraryFormatter extends AbstractUi5Formatter {
}

getNamespaceFromFsPath(fsPath) {
// Transform path to POSIX and remove any trailing slashes
const posixFsPath = fsPath.replace(/\\/g, "/").replace(/\/$/, "");
// Regex to ensure trailing slash
const rOptionalTrailingSlash = /\/?$/;

// Remove base path from fsPath
const posixBasePath = this.getSourceBasePath(true);
// Transform path to POSIX and ensure a trailing slash for correct comparison
const posixFsPath = fsPath.replace(/\\/g, "/").replace(rOptionalTrailingSlash, "/");
const posixBasePath = this.getSourceBasePath(true).replace(rOptionalTrailingSlash, "/");

// Can match /library/src as well as /library/src/some/namespace
const basePathPrefixRegExp = new RegExp(`^${posixBasePath}/?`);
if (posixBasePath === posixFsPath) {
// The given file system path does not contain a namespace path since it is equal to the source base path
// Therefore return an empty namespace
return "";
}

if (!basePathPrefixRegExp.test(posixFsPath)) {
if (posixBasePath === posixFsPath + "/") {
// The given file system path does not contain a namespace path
// It is equal to the source base path
// Therefore return an empty namespace
return "";
}
if (!posixFsPath.startsWith(posixBasePath)) {
throw new Error(`Given file system path ${posixFsPath} is not based on source base ` +
`path ${posixBasePath}.`);
}
const namespacePath = posixFsPath.replace(basePathPrefixRegExp, "");

// Remove base path from fsPath to get the namespace
let namespacePath = posixFsPath.replace(posixBasePath, "");

// Remove any leading and trailing slash
namespacePath = namespacePath.replace(/(?:^\/)|(?:\/$)/g, "");
return namespacePath;
}

Expand Down
18 changes: 16 additions & 2 deletions test/lib/types/library/LibraryFormatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -1454,11 +1454,25 @@ test("getNamespaceFromFsPath: fsPath is not based on base path", async (t) => {

const fsPath = "/some/different/path";
const err = t.throws(() => libraryFormatter.getNamespaceFromFsPath(fsPath));
t.deepEqual(err.message, `Given file system path /some/different/path is not based on source base ` +
`path /some/path.`,
t.deepEqual(err.message, `Given file system path /some/different/path/ is not based on source base ` +
`path /some/path/.`,
"Threw with correct error message");
});

test("getNamespaceFromFsPath: fsPath w/ regex metacharacters", async (t) => {
const myProject = clone(libraryETree);
myProject.resources.pathMappings = {
"/resources/": myProject.resources.configuration.paths.src
};

const libraryFormatter = new LibraryFormatter({project: myProject});
sinon.stub(libraryFormatter, "getSourceBasePath").returns("/some/(path");

const fsPath = "/some/(path/my/namespace";
const res = libraryFormatter.getNamespaceFromFsPath(fsPath);
t.deepEqual(res, "my/namespace", "Returned correct namespace");
});

test.serial("getPreloadExcludesFromDotLibrary: No excludes", async (t) => {
const log = {
verbose: sinon.stub()
Expand Down

0 comments on commit 2093562

Please sign in to comment.