Skip to content

Commit 2aa06b9

Browse files
TrottFishrock123
authored andcommitted
child_process: preserve argument type
A previous fix for a `maxBuffer` bug resulted in a change to the argument type for the `data` event on `child.stdin` and `child.stdout` when using `child_process.exec()`. This fixes the `maxBuffer` bug in a way that does not have that side effect. PR-URL: #7391 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Jackson Tian <shyvo1987@gmail.com> Fixes: #7342 Refs: #1901
1 parent 4a0fb6f commit 2aa06b9

5 files changed

Lines changed: 56 additions & 46 deletions

File tree

‎lib/child_process.js‎

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,12 @@ exports.execFile = function(file /*, args, options, callback*/) {
179179
// merge chunks
180180
varstdout;
181181
varstderr;
182-
if(!encoding){
183-
stdout=Buffer.concat(_stdout);
184-
stderr=Buffer.concat(_stderr);
185-
}else{
182+
if(encoding){
186183
stdout=_stdout;
187184
stderr=_stderr;
185+
}else{
186+
stdout=Buffer.concat(_stdout);
187+
stderr=Buffer.concat(_stderr);
188188
}
189189

190190
if(ex){
@@ -249,16 +249,16 @@ exports.execFile = function(file /*, args, options, callback*/) {
249249
child.stdout.setEncoding(encoding);
250250

251251
child.stdout.addListener('data',function(chunk){
252-
stdoutLen+=chunk.length;
252+
stdoutLen+=encoding ? Buffer.byteLength(chunk,encoding) : chunk.length;
253253

254254
if(stdoutLen>options.maxBuffer){
255255
ex=newError('stdout maxBuffer exceeded');
256256
kill();
257257
}else{
258-
if(!encoding)
259-
_stdout.push(chunk);
260-
else
258+
if(encoding)
261259
_stdout+=chunk;
260+
else
261+
_stdout.push(chunk);
262262
}
263263
});
264264
}
@@ -268,16 +268,16 @@ exports.execFile = function(file /*, args, options, callback*/) {
268268
child.stderr.setEncoding(encoding);
269269

270270
child.stderr.addListener('data',function(chunk){
271-
stderrLen+=chunk.length;
271+
stderrLen+=encoding ? Buffer.byteLength(chunk,encoding) : chunk.length;
272272

273273
if(stderrLen>options.maxBuffer){
274274
ex=newError('stderr maxBuffer exceeded');
275275
kill();
276276
}else{
277-
if(!encoding)
278-
_stderr.push(chunk);
279-
else
277+
if(encoding)
280278
_stderr+=chunk;
279+
else
280+
_stderr.push(chunk);
281281
}
282282
});
283283
}

‎test/known_issues/test-child-process-max-buffer.js‎

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'use strict';
2+
constcommon=require('../common');
3+
constassert=require('assert');
4+
constcp=require('child_process');
5+
6+
functioncheckFactory(streamName){
7+
returncommon.mustCall((err)=>{
8+
constmessage=`${streamName} maxBuffer exceeded`;
9+
assert.strictEqual(err.message,message);
10+
});
11+
}
12+
13+
{
14+
constcmd='echo "hello world"';
15+
16+
cp.exec(cmd,{maxBuffer: 5},checkFactory('stdout'));
17+
}
18+
19+
constunicode='中文测试';// length = 4, byte length = 12
20+
21+
{
22+
constcmd=`"${process.execPath}" -e "console.log('${unicode}');"`;
23+
24+
cp.exec(cmd,{maxBuffer: 10},checkFactory('stdout'));
25+
}
26+
27+
{
28+
constcmd=`"${process.execPath}" -e "console.('${unicode}');"`;
29+
30+
cp.exec(cmd,{maxBuffer: 10},checkFactory('stderr'));
31+
}

test/parallel/test-child-process-exec-stdout-data-string.js renamed to test/parallel/test-child-process-exec-stdout-stderr-data-string.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@ const common = require('../common');
44
constassert=require('assert');
55
constexec=require('child_process').exec;
66

7-
constexpectedCalls=2;
8-
9-
constcb=common.mustCall((data)=>{
10-
assert.strictEqual(typeofdata,'string');
11-
},expectedCalls);
7+
varstdoutCalls=0;
8+
varstderrCalls=0;
129

1310
constcommand=common.isWindows ? 'dir' : 'ls';
14-
exec(command).stdout.on('data',cb);
11+
exec(command).stdout.on('data',(data)=>{
12+
stdoutCalls+=1;
13+
});
1514

16-
exec('fhqwhgads').stderr.on('data',cb);
15+
exec('fhqwhgads').stderr.on('data',(data)=>{
16+
assert.strictEqual(typeofdata,'string');
17+
stderrCalls+=1;
18+
});
1719

20+
process.on('exit',()=>{
21+
assert(stdoutCalls>0);
22+
assert(stderrCalls>0);
23+
});

‎test/parallel/test-exec-max-buffer.js‎

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)