Skip to content

Commit 93d10bc

Browse files
addaleaxmcollina
authored andcommitted
process: allow reading from stdout/stderr sockets
Allow reading from stdio streams that are conventionally associated with process output, since this is only convention. This involves disabling the oddness around closing stdio streams. Its purpose is to prevent the file descriptors 0 through 2 from being closed, since doing so can lead to information leaks when new file descriptors are being opened; instead, not doing anything seems like a more reasonable choice. Fixes: nodejs/node#21203 PR-URL: nodejs/node#23053 Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 067b981 commit 93d10bc

8 files changed

+36
-19
lines changed

doc/api/errors.md

+20
Original file line numberDiff line numberDiff line change
@@ -1147,12 +1147,32 @@ A call was made and the UDP subsystem was not running.
11471147
<a id="ERR_STDERR_CLOSE"></a>
11481148
### ERR_STDERR_CLOSE
11491149

1150+
<!-- YAML
1151+
removed: REPLACEME
1152+
changes:
1153+
- version: REPLACEME
1154+
pr-url: https://github.com/nodejs/node/pull/23053
1155+
description: Rather than emitting an error, `process.stderr.end()` now
1156+
only closes the stream side but not the underlying resource,
1157+
making this error obsolete.
1158+
-->
1159+
11501160
An attempt was made to close the `process.stderr` stream. By design, Node.js
11511161
does not allow `stdout` or `stderr` streams to be closed by user code.
11521162

11531163
<a id="ERR_STDOUT_CLOSE"></a>
11541164
### ERR_STDOUT_CLOSE
11551165

1166+
<!-- YAML
1167+
removed: REPLACEME
1168+
changes:
1169+
- version: REPLACEME
1170+
pr-url: https://github.com/nodejs/node/pull/23053
1171+
description: Rather than emitting an error, `process.stderr.end()` now
1172+
only closes the stream side but not the underlying resource,
1173+
making this error obsolete.
1174+
-->
1175+
11561176
An attempt was made to close the `process.stdout` stream. By design, Node.js
11571177
does not allow `stdout` or `stderr` streams to be closed by user code.
11581178

doc/api/process.md

+2-4
Original file line numberDiff line numberDiff line change
@@ -1703,9 +1703,7 @@ important ways:
17031703

17041704
1. They are used internally by [`console.log()`][] and [`console.error()`][],
17051705
respectively.
1706-
2. They cannot be closed ([`end()`][] will throw).
1707-
3. They will never emit the [`'finish'`][] event.
1708-
4. Writes may be synchronous depending on what the stream is connected to
1706+
2. Writes may be synchronous depending on what the stream is connected to
17091707
and whether the system is Windows or POSIX:
17101708
- Files: *synchronous* on Windows and POSIX
17111709
- TTYs (Terminals): *asynchronous* on Windows, *synchronous* on POSIX
@@ -1925,7 +1923,6 @@ cases:
19251923

19261924

19271925
[`'exit'`]: #process_event_exit
1928-
[`'finish'`]: stream.html#stream_event_finish
19291926
[`'message'`]: child_process.html#child_process_event_message
19301927
[`'rejectionHandled'`]: #process_event_rejectionhandled
19311928
[`'uncaughtException'`]: #process_event_uncaughtexception
@@ -1937,6 +1934,7 @@ cases:
19371934
[`console.error()`]: console.html#console_console_error_data_args
19381935
[`console.log()`]: console.html#console_console_log_data_args
19391936
[`end()`]: stream.html#stream_writable_end_chunk_encoding_callback
1937+
[`domain`]: domain.html
19401938
[`net.Server`]: net.html#net_class_net_server
19411939
[`net.Socket`]: net.html#net_class_net_socket
19421940
[`process.argv`]: #process_process_argv

lib/internal/errors.js

-2
Original file line numberDiff line numberDiff line change
@@ -427,8 +427,6 @@ E('ERR_SOCKET_BUFFER_SIZE',
427427
(reason) => `Could not get or set buffer size: ${reason}`);
428428
E('ERR_SOCKET_CANNOT_SEND', 'Unable to send data');
429429
E('ERR_SOCKET_DGRAM_NOT_RUNNING', 'Not running');
430-
E('ERR_STDERR_CLOSE', 'process.stderr cannot be closed');
431-
E('ERR_STDOUT_CLOSE', 'process.stdout cannot be closed');
432430
E('ERR_UNKNOWN_BUILTIN_MODULE', (id) => `No such built-in module: ${id}`);
433431
E('ERR_UNKNOWN_FILE_EXTENSION', 'Unknown file extension: %s');
434432
E('ERR_UNKNOWN_MODULE_FORMAT', 'Unknown module format: %s');

lib/internal/process/stdio.js

+7-11
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
'use strict';
22

3-
const errors = require('internal/errors');
3+
const errors = require('internal/errors').codes;
44

55
exports.setup = setupStdio;
66

7+
function dummyDestroy(err, cb) { cb(err); }
8+
79
function setupStdio() {
810
var stdin;
911
var stdout;
@@ -13,11 +15,8 @@ function setupStdio() {
1315
if (stdout) return stdout;
1416
stdout = createWritableStdioStream(1);
1517
stdout.destroySoon = stdout.destroy;
16-
stdout._destroy = function(er, cb) {
17-
// Avoid errors if we already emitted
18-
er = er || new errors.Error('ERR_STDOUT_CLOSE');
19-
cb(er);
20-
};
18+
// Override _destroy so that the fd is never actually closed.
19+
stdout._destroy = dummyDestroy;
2120
if (stdout.isTTY) {
2221
process.on('SIGWINCH', () => stdout._refreshSize());
2322
}
@@ -28,11 +27,8 @@ function setupStdio() {
2827
if (stderr) return stderr;
2928
stderr = createWritableStdioStream(2);
3029
stderr.destroySoon = stderr.destroy;
31-
stderr._destroy = function(er, cb) {
32-
// Avoid errors if we already emitted
33-
er = er || new errors.Error('ERR_STDERR_CLOSE');
34-
cb(er);
35-
};
30+
// Override _destroy so that the fd is never actually closed.
31+
stdout._destroy = dummyDestroy;
3632
if (stderr.isTTY) {
3733
process.on('SIGWINCH', () => stderr._refreshSize());
3834
}

test/parallel/test-stdout-cannot-be-closed-child-process-pipe.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ function parent() {
2424
});
2525

2626
child.on('close', function(code, signal) {
27-
assert(code);
27+
assert.strictEqual(code, 0);
28+
assert.strictEqual(err, '');
2829
assert.strictEqual(out, 'foo');
29-
assert(/process\.stdout cannot be closed/.test(err));
3030
console.log('ok');
3131
});
3232
}

test/pseudo-tty/test-stdout-read.in

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Hello!

test/pseudo-tty/test-stdout-read.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
'use strict';
2+
const common = require('../common');
3+
process.stderr.on('data', common.mustCall(console.log));

test/pseudo-tty/test-stdout-read.out

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<Buffer 48 65 6c 6c 6f 21 0a>

0 commit comments

Comments
 (0)