From 3ee8f5342ccba4c2a56de3f2faa3747b73952159 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 7 Jul 2020 23:28:07 +0200 Subject: [PATCH] test: add regression tests for HTTP parser crash Since the tests only crash on v12.x, this commit adds separate regression tests. Refs: https://github.com/nodejs/node/issues/15102 PR-URL: https://github.com/nodejs/node/pull/34250 Refs: https://github.com/nodejs/node/issues/34016 Reviewed-By: Luigi Pinca --- ...t-http-sync-write-error-during-continue.js | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 test/parallel/test-http-sync-write-error-during-continue.js diff --git a/test/parallel/test-http-sync-write-error-during-continue.js b/test/parallel/test-http-sync-write-error-during-continue.js new file mode 100644 index 00000000000000..5476160942dadc --- /dev/null +++ b/test/parallel/test-http-sync-write-error-during-continue.js @@ -0,0 +1,53 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); +const MakeDuplexPair = require('../common/duplexpair'); + +// Regression test for the crash reported in +// https://github.com/nodejs/node/issues/15102 (httpParser.finish() is called +// during httpParser.execute()): + +{ + const { clientSide, serverSide } = MakeDuplexPair(); + + serverSide.on('data', common.mustCall((data) => { + assert.strictEqual(data.toString('utf8'), `\ +GET / HTTP/1.1 +Expect: 100-continue +Host: localhost:80 +Connection: close + +`.replace(/\n/g, '\r\n')); + + setImmediate(() => { + serverSide.write('HTTP/1.1 100 Continue\r\n\r\n'); + }); + })); + + const req = http.request({ + createConnection: common.mustCall(() => clientSide), + headers: { + 'Expect': '100-continue' + } + }); + req.on('continue', common.mustCall((res) => { + let sync = true; + + clientSide._writev = null; + clientSide._write = common.mustCall((chunk, enc, cb) => { + assert(sync); + // On affected versions of Node.js, the error would be emitted on `req` + // synchronously (i.e. before commit f663b31cc2aec), which would cause + // parser.finish() to be called while we are here in the 'continue' + // callback, which is inside a parser.execute() call. + + assert.strictEqual(chunk.length, 0); + clientSide.destroy(new Error('sometimes the code just doesn’t work'), cb); + }); + req.on('error', common.mustCall()); + req.end(); + + sync = false; + })); +}