@@ -157,15 +157,13 @@ exports.execFile = function(file /*, args, options, callback*/) {
157157 } ) ;
158158
159159 var encoding ;
160- var _stdout ;
161- var _stderr ;
160+ var stdoutState ;
161+ var stderrState ;
162+ var _stdout = [ ] ;
163+ var _stderr = [ ] ;
162164 if ( options . encoding !== 'buffer' && Buffer . isEncoding ( options . encoding ) ) {
163165 encoding = options . encoding ;
164- _stdout = '' ;
165- _stderr = '' ;
166166 } else {
167- _stdout = [ ] ;
168- _stderr = [ ] ;
169167 encoding = null ;
170168 }
171169 var stdoutLen = 0 ;
@@ -187,16 +185,23 @@ exports.execFile = function(file /*, args, options, callback*/) {
187185
188186 if ( ! callback ) return ;
189187
190- // merge chunks
191- var stdout ;
192- var stderr ;
193- if ( ! encoding ) {
194- stdout = Buffer . concat ( _stdout ) ;
195- stderr = Buffer . concat ( _stderr ) ;
196- } else {
197- stdout = _stdout ;
198- stderr = _stderr ;
199- }
188+ var stdout = Buffer . concat ( _stdout , stdoutLen ) ;
189+ var stderr = Buffer . concat ( _stderr , stderrLen ) ;
190+
191+ var stdoutEncoding = encoding ;
192+ var stderrEncoding = encoding ;
193+
194+ if ( stdoutState && stdoutState . decoder )
195+ stdoutEncoding = stdoutState . decoder . encoding ;
196+
197+ if ( stderrState && stderrState . decoder )
198+ stderrEncoding = stderrState . decoder . encoding ;
199+
200+ if ( stdoutEncoding )
201+ stdout = stdout . toString ( stdoutEncoding ) ;
202+
203+ if ( stderrEncoding )
204+ stderr = stderr . toString ( stderrEncoding ) ;
200205
201206 if ( ex ) {
202207 // Will be handled later
@@ -256,39 +261,45 @@ exports.execFile = function(file /*, args, options, callback*/) {
256261 }
257262
258263 if ( child . stdout ) {
259- if ( encoding )
260- child . stdout . setEncoding ( encoding ) ;
264+ stdoutState = child . stdout . _readableState ;
261265
262266 child . stdout . addListener ( 'data' , function ( chunk ) {
263- stdoutLen += chunk . length ;
267+ // If `child.stdout.setEncoding()` happened in userland, convert string to
268+ // Buffer.
269+ if ( stdoutState . decoder ) {
270+ chunk = Buffer . from ( chunk , stdoutState . decoder . encoding ) ;
271+ }
272+
273+ stdoutLen += chunk . byteLength ;
264274
265275 if ( stdoutLen > options . maxBuffer ) {
266276 ex = new Error ( 'stdout maxBuffer exceeded' ) ;
277+ stdoutLen -= chunk . byteLength ;
267278 kill ( ) ;
268279 } else {
269- if ( ! encoding )
270- _stdout . push ( chunk ) ;
271- else
272- _stdout += chunk ;
280+ _stdout . push ( chunk ) ;
273281 }
274282 } ) ;
275283 }
276284
277285 if ( child . stderr ) {
278- if ( encoding )
279- child . stderr . setEncoding ( encoding ) ;
286+ stderrState = child . stderr . _readableState ;
280287
281288 child . stderr . addListener ( 'data' , function ( chunk ) {
282- stderrLen += chunk . length ;
289+ // If `child.stderr.setEncoding()` happened in userland, convert string to
290+ // Buffer.
291+ if ( stderrState . decoder ) {
292+ chunk = Buffer . from ( chunk , stderrState . decoder . encoding ) ;
293+ }
294+
295+ stderrLen += chunk . byteLength ;
283296
284297 if ( stderrLen > options . maxBuffer ) {
285298 ex = new Error ( 'stderr maxBuffer exceeded' ) ;
299+ stderrLen -= chunk . byteLength ;
286300 kill ( ) ;
287301 } else {
288- if ( ! encoding )
289- _stderr . push ( chunk ) ;
290- else
291- _stderr += chunk ;
302+ _stderr . push ( chunk ) ;
292303 }
293304 } ) ;
294305 }
0 commit comments