kylefarris / clamscan

A robust ClamAV virus scanning library supporting scanning files, directories, and streams with local sockets, local/remote TCP, and local clamscan/clamdscan binaries (with failover).
MIT License
230 stars 68 forks source link

node 16 and aws-sdk #82

Closed Ockejanssen closed 2 years ago

Ockejanssen commented 2 years ago

When using node 16 the following code fails with Error [ERR_MULTIPLE_CALLBACK]: Callback called multiple times It does not happen on node 14.

It seems to be a problem with the highWaterMark. When it is low enough, it works.

const fs = require('fs'); const NodeClam = require('clamscan');

const {Writable} = require('stream');

class MyWritable extends Writable { constructor(options) { super(options); } _write(chunk, encoding, callback) { // console.log("xxxxxx", arguments); callback(); } }

async function test() { const source = fs.createReadStream('./README.md', {highWaterMark: 512}); const clamscan = await new NodeClam().init({clamdscan: {host: 'localhost', port: 3310}, debugMode: true}); const av = clamscan.passthrough(); av.on('finish', () => {console.log('--------------av finished');}); av.on('error', (error) => {console.log('--------------av error', error);}); av.on('scan-complete', (result) => {console.log('--------------av scan-complete', result);}); const mywritable = new MyWritable(); mywritable.on('error', (error) => {console.log('--------------mw error', error);}); mywritable.on('finish', () => {console.log('--------------mv finished');}); source.pipe(av).pipe(mywritable).on('finish', () => {console.log('all done', arguments);}); }

test();

kylefarris commented 2 years ago

I'm running low on bandwidth at the moment. I'm very open to pull requests. The source is pretty straightforward and well-documented. I'll have to address this sooner or later as we have production services that use clamscan that need to be updated to node 16.

But, yeah... any help would be great!

ngraef commented 2 years ago

See discussion on https://github.com/nodejs/node/issues/39535. This is caused by a behavior change in node 16 that tried to support Promise-returning stream implementation methods. That behavior was quickly deprecated because of the issues it caused. The error occurs when you try to return a Promise (async) and call the callback in the same function, like here in passthrough()'s Transform implementation:

https://github.com/kylefarris/clamscan/blob/c1d4f4c6114dbe74e7e40954944b70f3ac871b90/index.js#L1185

I'll open a PR with a fix.