@@ -146,15 +146,13 @@ exports.execFile = function(file /*, args, options, callback*/) {
146146 } ) ;
147147
148148 var encoding ;
149- var _stdout ;
150- var _stderr ;
149+ var stdoutState ;
150+ var stderrState ;
151+ var _stdout = [ ] ;
152+ var _stderr = [ ] ;
151153 if ( options . encoding !== 'buffer' && Buffer . isEncoding ( options . encoding ) ) {
152154 encoding = options . encoding ;
153- _stdout = '' ;
154- _stderr = '' ;
155155 } else {
156- _stdout = [ ] ;
157- _stderr = [ ] ;
158156 encoding = null ;
159157 }
160158 var stdoutLen = 0 ;
@@ -176,16 +174,23 @@ exports.execFile = function(file /*, args, options, callback*/) {
176174
177175 if ( ! callback ) return ;
178176
179- // merge chunks
180- var stdout ;
181- var stderr ;
182- if ( ! encoding ) {
183- stdout = Buffer . concat ( _stdout ) ;
184- stderr = Buffer . concat ( _stderr ) ;
185- } else {
186- stdout = _stdout ;
187- stderr = _stderr ;
188- }
177+ var stdout = Buffer . concat ( _stdout , stdoutLen ) ;
178+ var stderr = Buffer . concat ( _stderr , stderrLen ) ;
179+
180+ var stdoutEncoding = encoding ;
181+ var stderrEncoding = encoding ;
182+
183+ if ( stdoutState && stdoutState . decoder )
184+ stdoutEncoding = stdoutState . decoder . encoding ;
185+
186+ if ( stderrState && stderrState . decoder )
187+ stderrEncoding = stderrState . decoder . encoding ;
188+
189+ if ( stdoutEncoding )
190+ stdout = stdout . toString ( stdoutEncoding ) ;
191+
192+ if ( stderrEncoding )
193+ stderr = stderr . toString ( stderrEncoding ) ;
189194
190195 if ( ex ) {
191196 // Will be handled later
@@ -245,39 +250,45 @@ exports.execFile = function(file /*, args, options, callback*/) {
245250 }
246251
247252 if ( child . stdout ) {
248- if ( encoding )
249- child . stdout . setEncoding ( encoding ) ;
253+ stdoutState = child . stdout . _readableState ;
250254
251255 child . stdout . addListener ( 'data' , function ( chunk ) {
252- stdoutLen += chunk . length ;
256+ // If `child.stdout.setEncoding()` happened in userland, convert string to
257+ // Buffer.
258+ if ( stdoutState . decoder ) {
259+ chunk = Buffer . from ( chunk , stdoutState . decoder . encoding ) ;
260+ }
261+
262+ stdoutLen += chunk . byteLength ;
253263
254264 if ( stdoutLen > options . maxBuffer ) {
255265 ex = new Error ( 'stdout maxBuffer exceeded' ) ;
266+ stdoutLen -= chunk . byteLength ;
256267 kill ( ) ;
257268 } else {
258- if ( ! encoding )
259- _stdout . push ( chunk ) ;
260- else
261- _stdout += chunk ;
269+ _stdout . push ( chunk ) ;
262270 }
263271 } ) ;
264272 }
265273
266274 if ( child . stderr ) {
267- if ( encoding )
268- child . stderr . setEncoding ( encoding ) ;
275+ stderrState = child . stderr . _readableState ;
269276
270277 child . stderr . addListener ( 'data' , function ( chunk ) {
271- stderrLen += chunk . length ;
278+ // If `child.stderr.setEncoding()` happened in userland, convert string to
279+ // Buffer.
280+ if ( stderrState . decoder ) {
281+ chunk = Buffer . from ( chunk , stderrState . decoder . encoding ) ;
282+ }
283+
284+ stderrLen += chunk . byteLength ;
272285
273286 if ( stderrLen > options . maxBuffer ) {
274287 ex = new Error ( 'stderr maxBuffer exceeded' ) ;
288+ stderrLen -= chunk . byteLength ;
275289 kill ( ) ;
276290 } else {
277- if ( ! encoding )
278- _stderr . push ( chunk ) ;
279- else
280- _stderr += chunk ;
291+ _stderr . push ( chunk ) ;
281292 }
282293 } ) ;
283294 }
0 commit comments