This repository was archived by the owner on Feb 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
This repository was archived by the owner on Feb 12, 2024. It is now read-only.
PubSub splits binary message on 0x0a byte (EOL character) #3567
Copy link
Copy link
Closed
Labels
kind/bugA bug in existing code (including security flaws)A bug in existing code (including security flaws)kind/not-helia-issuestatus/blockedUnable to be worked further until needs are metUnable to be worked further until needs are met
Description
- Version:
{
version: '0.7.0',
commit: '',
repo: '10',
system: 'amd64/darwin',
golang: 'go1.14.4'
}
- Platform:
Darwin johnwehr.local 19.6.0 Darwin Kernel Version 19.6.0: Tue Nov 10 00:10:30 PST 2020; root:xnu-6153.141.10~1/RELEASE_X86_64 x86_64
- Subsystem:
ipfs-http-client/src/lib/multipart-request.node.js
Severity:
High
Description:
PubSub messages are split when the payload contains a 0x0a
character.
Steps to reproduce the error:
- Create a buffer filled with
0
- Write the
0x0a
byte into the buffer at any position pubsub.publish(...)
the buffer- Associated
pubsub.subscribe(...)
handlers receive two messages
const DaemonFactory = require('ipfsd-ctl');
const { default: AbortController } = require('abort-controller');
const ipfsBin = require('go-ipfs-dep').path();
const ipfsHttpModule = require('ipfs-http-client');
const assert = require('assert');
const { AssertionError } = assert;
const factory = DaemonFactory.createFactory({
type: 'go',
test: true,
ipfsBin,
ipfsHttpModule,
disposable: true,
args: ['--enable-pubsub-experiment'],
});
const options = {
ipfsOptions: {
config: {
Bootstrap: [],
Addresses: {
Swarm: [
'/ip4/0.0.0.0/tcp/0',
'/ip6/::/tcp/0',
],
},
Discovery: {
MDNS: {
Interval: 1,
Enabled: false,
},
},
},
},
};
(async () => {
// Spawn and connect nodes
const daemonA = await factory.spawn(options);
const ipfsA = daemonA.api;
const daemonB = await factory.spawn(options);
const { addresses } = await daemonB.api.id();
const ipfsB = daemonB.api;
await ipfsA.swarm.connect(addresses);
console.log(await ipfsA.version());
// {
// version: '0.7.0',
// commit: '',
// repo: '10',
// system: 'amd64/darwin',
// golang: 'go1.14.4'
// }
// Create an empty buffer, write a UInt8 0x0a at position 50
const buffer = Buffer.alloc(100);
buffer.writeUInt8(0x0a, 50); // 0x0a, 10, \n, EOL character
// Add pubsub subscription handler
const resultBufferPromise = new Promise((resolve) => {
// Receives two UInt8Arrays, length 50 and 49
ipfsB.pubsub.subscribe("example", ({ data }) => {
console.log(data.length);
resolve(Buffer.from(data));
});
});
// Publish the buffer
await ipfsA.pubsub.publish("example", Uint8Array.from(buffer));
// Result is length 49
const resultBuffer = await resultBufferPromise;
try {
assert(resultBuffer.equals(buffer));
console.log('Buffers are equal');
} catch(error) {
if(!(error instanceof AssertionError)) {
throw error;
}
console.log('Buffers are not equal'); // <--- This happens when the buffer contains 0x0a
}
// Clean up
await factory.clean();
})();
Metadata
Metadata
Assignees
Labels
kind/bugA bug in existing code (including security flaws)A bug in existing code (including security flaws)kind/not-helia-issuestatus/blockedUnable to be worked further until needs are metUnable to be worked further until needs are met