fix: close APT adversarial runtime gaps
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
const assert = require('node:assert/strict');
|
||||
const test = require('node:test');
|
||||
const { EventEmitter } = require('node:events');
|
||||
|
||||
const {
|
||||
LATEST_RELEASE_URL,
|
||||
@@ -9,6 +10,7 @@ const {
|
||||
MAX_BODY_BYTES,
|
||||
checkForUpdate,
|
||||
compareSemver,
|
||||
defaultRequest,
|
||||
} = require('../src/update-policy');
|
||||
|
||||
function response(body, overrides = {}) {
|
||||
@@ -188,3 +190,35 @@ test('unexpected HTTP and content types fail closed', async () => {
|
||||
'INVALID_CONTENT_TYPE',
|
||||
);
|
||||
});
|
||||
|
||||
test('default transport enforces an absolute deadline despite trickled response bytes', async () => {
|
||||
const request = new EventEmitter();
|
||||
const responseStream = new EventEmitter();
|
||||
request.destroyedWith = null;
|
||||
responseStream.destroyed = false;
|
||||
request.destroy = (error) => { request.destroyedWith = error; request.emit('error', error); };
|
||||
request.setTimeout = () => { throw new Error('inactivity timeout must not be used'); };
|
||||
responseStream.destroy = () => { responseStream.destroyed = true; };
|
||||
responseStream.headers = { 'content-type': 'application/json' };
|
||||
responseStream.statusCode = 200;
|
||||
let deadline;
|
||||
let cleared = false;
|
||||
const pending = defaultRequest({
|
||||
url: LATEST_RELEASE_URL,
|
||||
timeoutMs: 5000,
|
||||
maxBodyBytes: MAX_BODY_BYTES,
|
||||
httpsGet: (_url, _options, onResponse) => {
|
||||
onResponse(responseStream);
|
||||
return request;
|
||||
},
|
||||
setTimer: (callback, milliseconds) => { assert.equal(milliseconds, 5000); deadline = callback; return 7; },
|
||||
clearTimer: (timer) => { assert.equal(timer, 7); cleared = true; },
|
||||
});
|
||||
responseStream.emit('data', Buffer.from('{'));
|
||||
responseStream.emit('data', Buffer.from(' '));
|
||||
deadline();
|
||||
await rejectsWithCode(pending, 'REQUEST_TIMEOUT');
|
||||
assert.equal(responseStream.destroyed, true);
|
||||
assert.equal(request.destroyedWith.code, 'REQUEST_TIMEOUT');
|
||||
assert.equal(cleared, true);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user