Encoding of child_process.exec.stdout changed from String to Buffer in v6.2.1Β #7342
Copy link
Copy link
Closed
Labels
child_processIssues and PRs related to the child_process subsystem.Issues and PRs related to the child_process subsystem.confirmed-bugIssues and PRs for confirmed bugs.Issues and PRs for confirmed bugs.
Description
- Version: v6.2.1
- Platform: Darwin Kernel Version 15.5.0
- Subsystem: child_process
Somewhere between node v6.2.0 and v6.2.1 the encoding of the data passed to the 'on data' callback for the child_process.exec.stdout stream seems to have changed from String to Buffer.
Was this an intentional change, and what is the recommended way of setting the encoding for the exec stdout/stdio stream?
Thanks
Code example:
var exec = require('child_process').exec;
var keepAlive = setInterval(() => {}, 1000000000);
var e = exec('ls');
e.stdout.on('data', function(data) {
console.log('data: ', typeof data, data instanceof Buffer);
clearInterval(keepAlive);
});
with v6.2.0, output is data: string false
with v6.2.1, output is data: object true
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
child_processIssues and PRs related to the child_process subsystem.Issues and PRs related to the child_process subsystem.confirmed-bugIssues and PRs for confirmed bugs.Issues and PRs for confirmed bugs.
Activity
cjihrig commentedon Jun 20, 2016
I doubt this was an intended change. Without having bisected, my guess would be that the change happened in #6764.
e.stdout.setEncoding('utf8');I would recommend not using
exec()for this though.exec()is meant to run a process to completion, and then call back with the complete output.Trott commentedon Jun 22, 2016
Did the bisect, and @cjihrig is correct that #6764 introduced this bug.
test: add test for exec() known issue
Trott commentedon Jun 22, 2016
Opened a pull request to add a known-issue test for this: #7375
Trott commentedon Jun 22, 2016
I think the most sensible fix might be to revert that change from 6.x.x and put it in as a breaking change for 7.0.0 and update the documentation accordingly.
cjihrig commentedon Jun 22, 2016
I wonder if it is worth a second breaking change to v6 in order to do the revert. Working around this is straightforward, and the bug in question goes against the primary use case of
exec().Trott commentedon Jun 23, 2016
To work around it while preserving the old behavior, the default case will need to convert the string to a Buffer on every
dataevent. I would expect that to be a significant performance hit if there are lots of data events. (Although I haven't coded it up so I haven't run benchmarks to confirm this....)Or is there a different workaround you envision?
cjihrig commentedon Jun 23, 2016
There probably would be a performance hit. Not sure how significant. To reiterate, I don't think handling individual
dataevents is the intended/common use case forexec(). If we're going to put the same change back in v7, then it seems like a lot of flip-flopping of behavior.Trott commentedon Jun 23, 2016
I'll try to carve out a little time to code it up and benchmark to see the performance implications.
As far as flip-flopping, since it's flip-flopping on undocumented behavior that is definitely not the intended usage of
exec()and for which there are better APIs already available, it may be OK to flip-flop. It would look like this:string.object!string.While not ideal, I think that's OK if it's the only performant way to fix the
maxBufferbug.EDIT: Oh, wait, I suspect (now that I think about it) that you are suggesting just leaving things as they are and sorta kinda declaring this Not-A-Bug? That works for me too, but since there is at least one example of Real World Breakage due to this, I am more inclined towards revert-and-reintroduce-at-semver-major-time.
test: add test for exec() known issue
test: add test for exec() known issue
14 remaining items
child_process: preserve argument type