From b92c0cb15ca0b816db610f066de06af278ec171e 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 796803005dd534..2220f15f2b2f73 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -27,6 +27,7 @@ const { Map, MathMax, + Number, NumberIsSafeInteger, ObjectCreate, ObjectDefineProperties, @@ -174,7 +175,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) { @@ -1614,7 +1618,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)) { @@ -1747,7 +1751,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) {