Changes: Preserve incomplete work and blocker metadata for S00-003. This checkpoint does not mark implementation accepted. Validation: Session ended with status blocked. Blocker: S00-003 cannot attest parser limits: Stanza 12.22.1 exposes no resource bounds and its persistent WebSocket parser accepts large/deep XML and reassembles incomplete documents across separate input messages. Task: S00-003 Agent: auto-protocol-902594b44429 Role: protocol Action: claim Status: blocked Task title: Проверить XMPP WSS/auth библиотеку
58 lines
2.3 KiB
JavaScript
58 lines
2.3 KiB
JavaScript
// Bounded diagnostic of the stock parser; passing means the defect reproduced.
|
|
// No network, credentials, vendor patch, or production implementation.
|
|
import assert from 'node:assert/strict';
|
|
import {createRequire} from 'node:module';
|
|
const require = createRequire(import.meta.url);
|
|
const Client = require('stanza/Client').default;
|
|
const {StreamParser} = require('stanza/jxt');
|
|
assert.equal(require('stanza/package.json').version, '12.22.1');
|
|
const tick = () => new Promise(resolve => setImmediate(resolve));
|
|
function harness() {
|
|
const client = new Client({autoReconnect: false});
|
|
// Same parser options as shipped transports/websocket.js.
|
|
const parser = new StreamParser({registry: client.stanzas,
|
|
wrappedStream: false, allowComments: false});
|
|
const received = [], errors = [];
|
|
parser.on('data', value => received.push(value));
|
|
parser.on('error', error => errors.push(error));
|
|
return {parser, received, errors};
|
|
}
|
|
const opening = '<message xmlns="jabber:client"><body>';
|
|
const closing = '</body></message>';
|
|
|
|
const split = harness();
|
|
split.parser.write(opening);
|
|
for (let i = 0; i < 16; i++) split.parser.write('a'.repeat(4096));
|
|
await tick();
|
|
assert.equal(split.errors.length, 0);
|
|
assert.equal(split.received.length, 0);
|
|
assert.equal(split.parser.destroyed, false);
|
|
split.parser.write(closing);
|
|
await tick();
|
|
assert.equal(split.errors.length, 0);
|
|
assert.equal(split.received.length, 1);
|
|
assert.equal(split.received[0].stanza.body.length, 65536);
|
|
split.parser.destroy();
|
|
console.log('stock: 18 separate writes reassembled into one 65536-byte body; no error');
|
|
|
|
const large = harness();
|
|
large.parser.write(opening + 'b'.repeat(1048576) + closing);
|
|
await tick();
|
|
assert.equal(large.errors.length, 0);
|
|
assert.equal(large.received.length, 1);
|
|
assert.equal(large.received[0].stanza.body.length, 1048576);
|
|
large.parser.destroy();
|
|
console.log('stock: 1048576-byte body accepted; no error');
|
|
|
|
const deep = harness();
|
|
deep.parser.write('<message xmlns="jabber:client">' + '<x>'.repeat(256) +
|
|
'</x>'.repeat(256) + '</message>');
|
|
await tick();
|
|
assert.equal(deep.errors.length, 0);
|
|
assert.equal(deep.received.length, 1);
|
|
let element = deep.received[0].xml, depth = 0;
|
|
while (element.children[0]) {element = element.children[0]; depth++;}
|
|
assert.equal(depth, 256);
|
|
deep.parser.destroy();
|
|
console.log('stock: 256 nested child elements accepted; no error');
|