node/test/parallel/test-http-parser-bad-ref.js
James M Snell 1744205ff5
http: move process.binding('http_parser') to internalBinding
Refs: https://github.com/nodejs/node/issues/22160

PR-URL: https://github.com/nodejs/node/pull/22329
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Jon Moss <me@jonathanmoss.me>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
2018-08-18 13:01:21 -07:00

89 lines
2.0 KiB
JavaScript

'use strict';
// Run this program with valgrind or efence with --expose_gc to expose the
// problem.
// Flags: --expose_gc --expose-internals
require('../common');
const assert = require('assert');
const { internalBinding } = require('internal/test/binding');
const { HTTPParser } = internalBinding('http_parser');
const kOnHeaders = HTTPParser.kOnHeaders | 0;
const kOnHeadersComplete = HTTPParser.kOnHeadersComplete | 0;
const kOnBody = HTTPParser.kOnBody | 0;
const kOnMessageComplete = HTTPParser.kOnMessageComplete | 0;
let headersComplete = 0;
let messagesComplete = 0;
function flushPool() {
Buffer.allocUnsafe(Buffer.poolSize - 1);
global.gc();
}
function demoBug(part1, part2) {
flushPool();
const parser = new HTTPParser('REQUEST');
parser.headers = [];
parser.url = '';
parser[kOnHeaders] = function(headers, url) {
parser.headers = parser.headers.concat(headers);
parser.url += url;
};
parser[kOnHeadersComplete] = function(info) {
headersComplete++;
console.log('url', info.url);
};
parser[kOnBody] = () => {};
parser[kOnMessageComplete] = function() {
messagesComplete++;
};
// We use a function to eliminate references to the Buffer b
// We want b to be GCed. The parser will hold a bad reference to it.
(function() {
const b = Buffer.from(part1);
flushPool();
console.log('parse the first part of the message');
parser.execute(b, 0, b.length);
})();
flushPool();
(function() {
const b = Buffer.from(part2);
console.log('parse the second part of the message');
parser.execute(b, 0, b.length);
parser.finish();
})();
flushPool();
}
demoBug('POST /1', '/22 HTTP/1.1\r\n' +
'Content-Type: text/plain\r\n' +
'Content-Length: 4\r\n\r\n' +
'pong');
demoBug('POST /1/22 HTTP/1.1\r\n' +
'Content-Type: tex', 't/plain\r\n' +
'Content-Length: 4\r\n\r\n' +
'pong');
process.on('exit', function() {
assert.strictEqual(2, headersComplete);
assert.strictEqual(2, messagesComplete);
console.log('done!');
});