Skip to content

Commit

Permalink
fs: fix realpath{Sync} on resolving pipes/sockets
Browse files Browse the repository at this point in the history
PR-URL: #13028
Reviewed-By: Refael Ackermann <refack@gmail.com>
  • Loading branch information
ebraminio authored and jasnell committed May 28, 2017
1 parent f077e51 commit d99b7bc
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 5 deletions.
12 changes: 12 additions & 0 deletions doc/api/fs.md
Original file line number Diff line number Diff line change
Expand Up @@ -1840,6 +1840,9 @@ Synchronous version of [`fs.read()`][]. Returns the number of `bytesRead`.
<!-- YAML
added: v0.1.31
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/13028
description: Pipe/Socket resolve support was added.
- version: v7.6.0
pr-url: https://github.com/nodejs/node/pull/10739
description: The `path` parameter can be a WHATWG `URL` object using
Expand Down Expand Up @@ -1872,10 +1875,16 @@ object with an `encoding` property specifying the character encoding to use for
the path passed to the callback. If the `encoding` is set to `'buffer'`,
the path returned will be passed as a `Buffer` object.

*Note*: If `path` resolves to a socket or a pipe, the function will return a
system dependent name for that object.

## fs.realpathSync(path[, options])
<!-- YAML
added: v0.1.31
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/13028
description: Pipe/Socket resolve support was added.
- version: v7.6.0
pr-url: https://github.com/nodejs/node/pull/10739
description: The `path` parameter can be a WHATWG `URL` object using
Expand All @@ -1902,6 +1911,9 @@ object with an `encoding` property specifying the character encoding to use for
the returned value. If the `encoding` is set to `'buffer'`, the path returned
will be passed as a `Buffer` object.

*Note*: If `path` resolves to a socket or a pipe, the function will return a
system dependent name for that object.

## fs.rename(oldPath, newPath, callback)
<!-- YAML
added: v0.0.2
Expand Down
18 changes: 13 additions & 5 deletions lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
'use strict';

const constants = process.binding('constants').fs;
const { S_IFMT, S_IFREG, S_IFLNK } = constants;
const { S_IFIFO, S_IFLNK, S_IFMT, S_IFREG, S_IFSOCK } = constants;
const util = require('util');
const pathModule = require('path');
const { isUint8Array } = process.binding('util');
Expand Down Expand Up @@ -228,11 +228,11 @@ Stats.prototype.isSymbolicLink = function() {
};

Stats.prototype.isFIFO = function() {
return this._checkModeProperty(constants.S_IFIFO);
return this._checkModeProperty(S_IFIFO);
};

Stats.prototype.isSocket = function() {
return this._checkModeProperty(constants.S_IFSOCK);
return this._checkModeProperty(S_IFSOCK);
};

const statValues = binding.getStatValues();
Expand Down Expand Up @@ -1625,8 +1625,12 @@ fs.realpathSync = function realpathSync(p, options) {
pos = result + 1;
}

// continue if not a symlink
// continue if not a symlink, break if a pipe/socket
if (knownHard[base] || (cache && cache.get(base) === base)) {
if ((statValues[1/*mode*/] & S_IFMT) === S_IFIFO ||
(statValues[1/*mode*/] & S_IFMT) === S_IFSOCK) {
break;
}
continue;
}

Expand Down Expand Up @@ -1752,8 +1756,12 @@ fs.realpath = function realpath(p, options, callback) {
pos = result + 1;
}

// continue if not a symlink
// continue if not a symlink, break if a pipe/socket
if (knownHard[base]) {
if ((statValues[1/*mode*/] & S_IFMT) === S_IFIFO ||
(statValues[1/*mode*/] & S_IFMT) === S_IFSOCK) {
return callback(null, encodeRealpathResult(p, options));
}
return process.nextTick(LOOP);
}

Expand Down
34 changes: 34 additions & 0 deletions test/parallel/test-fs-realpath-pipe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use strict';

const common = require('../common');

if (common.isWindows || common.isAix) {
common.skip(`No /dev/stdin on ${process.platform}.`);
return;
}

const assert = require('assert');

const { spawnSync } = require('child_process');

for (const code of [
`require('fs').realpath('/dev/stdin', (err, resolvedPath) => {
if (err) {
process.exit(1);
}
if (resolvedPath) {
process.exit(2);
}
});`,
`try {
if (require('fs').realpathSync('/dev/stdin')) {
process.exit(2);
}
} catch (e) {
process.exit(1);
}`
]) {
assert.strictEqual(spawnSync(process.execPath, ['-e', code], {
stdio: 'pipe'
}).status, 2);
}

0 comments on commit d99b7bc

Please sign in to comment.