diff --git a/polyfills.js b/polyfills.js index 2798050..39d8176 100644 --- a/polyfills.js +++ b/polyfills.js @@ -56,6 +56,14 @@ function patch (fs) { fs.fchmodSync = chmodFixSync(fs.fchmodSync) fs.lchmodSync = chmodFixSync(fs.lchmodSync) + fs.stat = statFix(fs.stat) + fs.fstat = statFix(fs.fstat) + fs.lstat = statFix(fs.lstat) + + fs.statSync = statFixSync(fs.statSync) + fs.fstatSync = statFixSync(fs.fstatSync) + fs.lstatSync = statFixSync(fs.lstatSync) + // if lchmod/lchown do not exist, then make them no-ops if (!fs.lchmod) { fs.lchmod = function (path, mode, cb) { @@ -246,6 +254,32 @@ function chownFixSync (orig) { } } + +function statFix (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target, cb) { + return orig.call(fs, target, function (er, stats) { + if (stats.uid < 0) stats.uid += 0x100000000 + if (stats.gid < 0) stats.gid += 0x100000000 + if (cb) cb.apply(this, arguments) + }) + } +} + +function statFixSync (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target) { + var stats = orig.call(fs, target) + if (stats.uid < 0) stats.uid += 0x100000000 + if (stats.gid < 0) stats.gid += 0x100000000 + return stats; + } +} + // ENOSYS means that the fs doesn't support the op. Just ignore // that, because it doesn't matter. // diff --git a/test/stats-uid-gid.js b/test/stats-uid-gid.js new file mode 100644 index 0000000..e3476f7 --- /dev/null +++ b/test/stats-uid-gid.js @@ -0,0 +1,29 @@ +'use strict'; +var test = require('tap').test +var util = require('util') +var fs = require('fs') + +// mock fs.statSync to return signed uids/gids +var realStatSync = fs.statSync +fs.statSync = function(path) { + var stats = realStatSync.call(fs, path) + stats.uid = -2 + stats.gid = -2 + return stats +} + +var gfs = require('../graceful-fs.js') + +test('graceful fs uses same stats constructor as fs', function (t) { + t.equal(gfs.Stats, fs.Stats, 'should reference the same constructor') + + if (!process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH) { + t.equal(fs.statSync(__filename).uid, -2) + t.equal(fs.statSync(__filename).gid, -2) + } + + t.equal(gfs.statSync(__filename).uid, 0xfffffffe) + t.equal(gfs.statSync(__filename).gid, 0xfffffffe) + + t.end() +})