From 01ff9c27da3d35e37aad5e0f431529f4cd369004 Mon Sep 17 00:00:00 2001 From: Denys Otrishko Date: Thu, 18 Jun 2020 18:49:59 +0300 Subject: [PATCH 1/2] fs: fix realpath inode link caching The `fs.realpath` / `fs.realpathSync` cache already seen symbolic links using the inode number which may be longer that max supported JS number (2**53) and will therefore be incorrectly handled by possibly entering infinite loop of calling stat on the same node. This PR changes those functions (where appropriate) to use bigint for inode numbers. Fixes: https://github.com/nodejs/node/issues/33936 --- lib/fs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/fs.js b/lib/fs.js index 8d2a1e044ee08f..23609e257f3652 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1650,7 +1650,7 @@ function realpathSync(p, options) { const baseLong = pathModule.toNamespacedPath(base); const ctx = { path: base }; - const stats = binding.lstat(baseLong, false, undefined, ctx); + const stats = binding.lstat(baseLong, true, undefined, ctx); handleErrorFromBinding(ctx); if (!isFileType(stats, S_IFLNK)) { @@ -1783,7 +1783,7 @@ function realpath(p, options, callback) { return process.nextTick(LOOP); } - return fs.lstat(base, gotStat); + return fs.lstat(base, { bigint: true }, gotStat); } function gotStat(err, stats) { From c0b8202a7d8e3ba20fd6b5c0d6feb475e6b224a4 Mon Sep 17 00:00:00 2001 From: Denys Otrishko Date: Thu, 18 Jun 2020 19:48:17 +0300 Subject: [PATCH 2/2] fixup! fs: fix realpath inode link caching --- lib/fs.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/fs.js b/lib/fs.js index 23609e257f3652..c32b9cbe863afc 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -31,6 +31,7 @@ const kIoMaxLength = 2 ** 31 - 1; const { Map, MathMax, + Number, NumberIsSafeInteger, ObjectCreate, ObjectDefineProperties, @@ -182,7 +183,10 @@ const isFd = isUint32; function isFileType(stats, fileType) { // Use stats array directly to avoid creating an fs.Stats instance just for // our internal use. - return (stats[1/* mode */] & S_IFMT) === fileType; + let mode = stats[1]; + if (typeof mode === 'bigint') + mode = Number(mode); + return (mode & S_IFMT) === fileType; } function access(path, mode, callback) {