@@ -146,15 +146,13 @@ exports.execFile = function(file /*, args, options, callback*/) {
146
146
} ) ;
147
147
148
148
var encoding ;
149
- var _stdout ;
150
- var _stderr ;
149
+ var stdoutState ;
150
+ var stderrState ;
151
+ var _stdout = [ ] ;
152
+ var _stderr = [ ] ;
151
153
if ( options . encoding !== 'buffer' && Buffer . isEncoding ( options . encoding ) ) {
152
154
encoding = options . encoding ;
153
- _stdout = '' ;
154
- _stderr = '' ;
155
155
} else {
156
- _stdout = [ ] ;
157
- _stderr = [ ] ;
158
156
encoding = null ;
159
157
}
160
158
var stdoutLen = 0 ;
@@ -176,16 +174,23 @@ exports.execFile = function(file /*, args, options, callback*/) {
176
174
177
175
if ( ! callback ) return ;
178
176
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 ) ;
189
194
190
195
if ( ex ) {
191
196
// Will be handled later
@@ -245,39 +250,45 @@ exports.execFile = function(file /*, args, options, callback*/) {
245
250
}
246
251
247
252
if ( child . stdout ) {
248
- if ( encoding )
249
- child . stdout . setEncoding ( encoding ) ;
253
+ stdoutState = child . stdout . _readableState ;
250
254
251
255
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 ;
253
263
254
264
if ( stdoutLen > options . maxBuffer ) {
255
265
ex = new Error ( 'stdout maxBuffer exceeded' ) ;
266
+ stdoutLen -= chunk . byteLength ;
256
267
kill ( ) ;
257
268
} else {
258
- if ( ! encoding )
259
- _stdout . push ( chunk ) ;
260
- else
261
- _stdout += chunk ;
269
+ _stdout . push ( chunk ) ;
262
270
}
263
271
} ) ;
264
272
}
265
273
266
274
if ( child . stderr ) {
267
- if ( encoding )
268
- child . stderr . setEncoding ( encoding ) ;
275
+ stderrState = child . stderr . _readableState ;
269
276
270
277
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 ;
272
285
273
286
if ( stderrLen > options . maxBuffer ) {
274
287
ex = new Error ( 'stderr maxBuffer exceeded' ) ;
288
+ stderrLen -= chunk . byteLength ;
275
289
kill ( ) ;
276
290
} else {
277
- if ( ! encoding )
278
- _stderr . push ( chunk ) ;
279
- else
280
- _stderr += chunk ;
291
+ _stderr . push ( chunk ) ;
281
292
}
282
293
} ) ;
283
294
}
0 commit comments