Version
v19.4.0
Platform
Microsoft Windows NT 10.0.22000.0 x64
Subsystem
node:stream
What steps will reproduce the bug?
Create a new stream.Writeable and supply an invalid encoding for defaultEncoding. It will accept the encoding just fine, which can lead to some strange side effects.
For a very quick test, just to show that it does not validate it:
new (require('node:stream').Writable)({defaultEncoding: 'some invalid encoding'});
For a more complete test that shows more of its effects:
const stream = require('node:stream');
console.log('stream 1');
const s1 = new stream.Writable({
defaultEncoding: 'my invalid encoding',
write(chunk, enc, cb) {
console.log('dat', chunk);
console.log('enc', enc);
cb();
}
});
// output:
//TypeError: Unknown encoding: my invalid encoding
//...
try {
s1.write('test data');
} catch (err) {
console.error(err);
}
/* ============================== */
console.log('\nstream 2');
const s2 = new stream.Writable({
defaultEncoding: 'my invalid encoding',
decodeStrings: false,
write(chunk, enc, cb) {
console.log('dat', chunk);
console.log('enc', enc);
cb();
}
});
// output:
//dat test data
//enc my invalid encoding
s2.write('test data');
/* ============================== */
console.log('\nstream 3');
const s3 = new stream.Writable({
defaultEncoding: {an: 'object'},
write(chunk, enc, cb) {
console.log('dat', chunk);
console.log('enc', enc);
cb();
}
});
// output:
//dat <Buffer 74 65 73 74 20 64 61 74 61>
//enc buffer
s3.write('test data');
/* ============================== */
console.log('\nstream 4');
const s4 = new stream.Transform({
defaultEncoding: 'my invalid encoding',
transform(chunk, enc, cb) {
console.log('dat', chunk);
console.log('enc', enc);
cb(chunk);
}
});
// output:
//TypeError: Unknown encoding: my invalid encoding
//...
try {
s4.write('test data');
} catch (err) {
console.error(err);
}
/* ============================== */
console.log('\nnode:crypto test');
console.log('crypto.createCipheriv');
const crypto = require('node:crypto');
const encrypt = crypto.createCipheriv('aes-128-gcm', crypto.randomBytes(16), crypto.randomBytes(16), {defaultEncoding: 'an invalid encoding'});
encrypt.on('data', (chunk) => {
console.log('data received', chunk);
});
encrypt.write('some more data');
encrypt.end();
How often does it reproduce? Is there a required condition?
As far as I can tell, it always reproduces.
What is the expected behavior?
I would expect the stream.Writeable constructor to validate the defaultEncoding option and throw an error if it is invalid.
It still can throw an error with a call to writeable.write if objectMode is false, decodeStrings is true, the chunk is a string, and no encoding is specified in the write call. Weirdly enough, it doesn't throw an error if the defaultEncoding is something other than a string, like a number or object, and converts the string provided in the write call to a buffer anyway.
const stream = require('node:stream');
// would expect an error
new stream.Writable({defaultEncoding: 'some invalid encoding'});
// would very much expect an error
new stream.Writable({defaultEncoding: 42}).write('a string');
const s = new stream.Writeable();
// throws an error, which is exactly what I would expect
s.setDefaultEncoding('some invalid encoding');
// also throws an error (expected)
s.write('a string', 42);
What do you see instead?
It does not validate invalid default encodings in the constructor, and only throws an error if the invalid default encoding is used (such as if a string is provided in a write call with no other encoding specified).
Additional information
Trying a similar thing with stream.Readable throws an error instead.
// throws an error (which is expected)
new (require('node:stream').Readable)({encoding: 'some invalid encoding'});
Version
v19.4.0
Platform
Microsoft Windows NT 10.0.22000.0 x64
Subsystem
node:stream
What steps will reproduce the bug?
Create a new
stream.Writeableand supply an invalid encoding fordefaultEncoding. It will accept the encoding just fine, which can lead to some strange side effects.For a very quick test, just to show that it does not validate it:
For a more complete test that shows more of its effects:
How often does it reproduce? Is there a required condition?
As far as I can tell, it always reproduces.
What is the expected behavior?
I would expect the
stream.Writeableconstructor to validate thedefaultEncodingoption and throw an error if it is invalid.It still can throw an error with a call to
writeable.writeifobjectModeis false,decodeStringsis true, thechunkis a string, and no encoding is specified in the write call. Weirdly enough, it doesn't throw an error if thedefaultEncodingis something other than a string, like a number or object, and converts the string provided in the write call to a buffer anyway.What do you see instead?
It does not validate invalid default encodings in the constructor, and only throws an error if the invalid default encoding is used (such as if a string is provided in a write call with no other encoding specified).
Additional information
Trying a similar thing with
stream.Readablethrows an error instead.