From 4d145c1d3afee7ff86ad5f2771883acfdefd5d3c Mon Sep 17 00:00:00 2001 From: Karl Semich Date: Tue, 5 Nov 2019 06:48:57 -0500 Subject: [PATCH 1/2] Fix for handling symlinks to http-backed files --- src/CacheFS.js | 5 +---- src/PromisifiedFS.js | 5 +++++ .../__fixtures__/test-folder/.superblock.txt | 2 ++ src/__tests__/__fixtures__/test-folder/2/a.txt | 1 + src/__tests__/fallback.spec.js | 12 +++++++++++- src/path.js | 13 +++++++++++++ 6 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 src/__tests__/__fixtures__/test-folder/2/a.txt diff --git a/src/CacheFS.js b/src/CacheFS.js index 0345b98..56ded71 100755 --- a/src/CacheFS.js +++ b/src/CacheFS.js @@ -115,10 +115,7 @@ module.exports = class CacheFS { if (follow) { const stat = dir.get(STAT) if (stat.type === 'symlink') { - let target = stat.target - if (!target.startsWith('/')) { - target = path.normalize(path.join(partialPath, target)) - } + let target = path.resolve(partialPath, stat.target) dir = this._lookup(target) } if (!partialPath) { diff --git a/src/PromisifiedFS.js b/src/PromisifiedFS.js index 86ad0ff..b3accab 100644 --- a/src/PromisifiedFS.js +++ b/src/PromisifiedFS.js @@ -150,6 +150,11 @@ module.exports = class PromisifiedFS { const stat = this._cache.stat(filepath); let data = await this._idb.readFile(stat.ino) if (!data && this._http) { + let lstat = this._cache.lstat(filepath) + while (lstat.type === 'symlink') { + filepath = path.resolve(path.dirname(filepath), lstat.target) + lstat = this._cache.lstat(filepath) + } data = await this._http.readFile(filepath) } if (data && encoding === "utf8") { diff --git a/src/__tests__/__fixtures__/test-folder/.superblock.txt b/src/__tests__/__fixtures__/test-folder/.superblock.txt index 7e85433..e8141a6 100644 --- a/src/__tests__/__fixtures__/test-folder/.superblock.txt +++ b/src/__tests__/__fixtures__/test-folder/.superblock.txt @@ -6,6 +6,8 @@ d.txt 100644 14 1545621340683.4724 e.txt 100644 14 1545621349775.4539 f.txt 100644 14 1545621356008.1582 +2 40775 + a.txt 100664 14 1572953161955.4033 a.txt 100644 14 1545621375109 b.txt 100644 14 1545621255760.9512 c.txt 100644 14 1545621290070.7742 diff --git a/src/__tests__/__fixtures__/test-folder/2/a.txt b/src/__tests__/__fixtures__/test-folder/2/a.txt new file mode 100644 index 0000000..c790b89 --- /dev/null +++ b/src/__tests__/__fixtures__/test-folder/2/a.txt @@ -0,0 +1 @@ +Hello from "a" \ No newline at end of file diff --git a/src/__tests__/fallback.spec.js b/src/__tests__/fallback.spec.js index b880175..a420cf9 100644 --- a/src/__tests__/fallback.spec.js +++ b/src/__tests__/fallback.spec.js @@ -18,7 +18,7 @@ describe("http fallback", () => { it("read root dir", done => { fs.readdir("/", (err, data) => { expect(err).toBe(null); - expect(data).toEqual(['0', '1', 'a.txt', 'b.txt', 'c.txt']) + expect(data).toEqual(['0', '1', '2', 'a.txt', 'b.txt', 'c.txt']) done(); }); }); @@ -52,6 +52,16 @@ describe("http fallback", () => { done(); }); }); + it("make a symlink and read file /2/a.txt through it", done => { + fs.symlink("a.txt", "/2/symlink.txt", (err) => { + expect(err).toBe(null); + fs.readFile("/2/symlink.txt", 'utf8', (err, data) => { + expect(err).toBe(null); + expect(data).toEqual('Hello from "a"'); + done(); + }); + }); + }); }); describe("writeFile", () => { diff --git a/src/path.js b/src/path.js index 566f00c..e45952f 100755 --- a/src/path.js +++ b/src/path.js @@ -7,6 +7,18 @@ function normalizePath(path) { return joinPath(...parts); } +function resolvePath(...paths) { + let result = ''; + for (let path of paths) { + if (path.startsWith('/')) { + result = path; + } else { + result = normalizePath(joinPath(result, path)); + } + } + return result; +} + function joinPath(...parts) { if (parts.length === 0) return ""; let path = parts.join("/"); @@ -91,4 +103,5 @@ module.exports = { split: splitPath, basename, dirname, + resolve: resolvePath, }; From 68d283b543519435b7b0aaa7ecbf5f2d773021bc Mon Sep 17 00:00:00 2001 From: William Hilton Date: Sat, 16 Nov 2019 10:33:02 -0500 Subject: [PATCH 2/2] chore: ci