From bd8a7196fc15ab7ae4976c3fb728267ab6864a67 Mon Sep 17 00:00:00 2001 From: Denys Otrishko Date: Thu, 18 Jun 2020 18:49:59 +0300 Subject: [PATCH] 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 PR-URL: https://github.com/nodejs/node/pull/33945 Reviewed-By: James M Snell Reviewed-By: Ben Noordhuis Reviewed-By: Anna Henningsen --- lib/fs.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/fs.js b/lib/fs.js index c85389baec5a7f..229167fc51eac6 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) { @@ -1672,7 +1676,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)) { @@ -1805,7 +1809,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) {