Skip to content

bug: Data corruption when sending binary #210

Open

Description

@DomNomNom

Hi, I was sending icons over websocket OSC and some of them got corrupted.
It seemed like larger ones were fine but smaller ones have trouble.

I've made a minimal example that shows the problem clearly:

const http = require('node:http');
const WebSocket = require("ws");
const osc = require('osc');

// The data we want to send
const bytes = new Uint8Array([ 4,4,4,4,4,4 ]);

// server
const hostname = '127.0.0.1';
const port = 7000;
const server = http.createServer(async (req, res) => {});
server.listen(port, hostname, () => {
    // console.log(`Server running at http://${hostname}:${port}/`);
});
const wss = new WebSocket.Server({ server });
wss.on("connection", function(socket) {
    const osc_port = new osc.WebSocketPort({
        socket: socket,
        metadata: true
    });
    osc_port.on("message", (osc_msg) => {
        // console.log('rx osc_msg=', osc_msg)
        console.log("rx osc_msg.args[0].value=", osc_msg.args[0].value)
        console.log();
        process.exit();
    });
});

// client
const ui_url = `ws://${hostname}:${port}/`;
ui_port = new osc.WebSocketPort({
    // url: ui_url,
    metadata: true,
    socket: new WebSocket(ui_url),
});
ui_port.on("ready", function () {
    const osc_msg = {
      address: '/foo',
      args: [
        { type: 'b', value: bytes }
      ]
    };
    // console.log('tx osc_msg=', osc_msg)
    console.log('tx osc_msg.args[0].value=', osc_msg.args[0].value)
    ui_port.send(osc_msg);
});

want:

tx osc_msg.args[0].value= Uint8Array(6) [ 4, 4, 4, 4, 4, 4 ]
rx osc_msg.args[0].value= Uint8Array(6) [ 4, 4, 4, 4, 4, 4 ]

got:

tx osc_msg.args[0].value= Uint8Array(6) [ 4, 4, 4, 4, 4, 4 ]
rx osc_msg.args[0].value= Uint8Array(6) [ 0, 0, 0, 0, 0, 6 ]

Activity

  1. colinbdclark commented on Nov 10, 2024

    @colinbdclark
    Owner

    Hi @DomNomNom, my apologies for the very slow response. Thank you so much for the simplified test case for this issue, it makes a huge difference in trying to triage issues like this.

    Since it's been a while, did you ever come up with a workaround or fix?

    It seems like the bug you've found is legit, though so far I'm puzzled by it. It looks like the output you're receiving is reading the zero padding and the four-byte size of the binary blob, so there's an incorrect offset somewhere.

    But, playing with your example, it appears that the bug is not in the low-level OSC API, where all the low-level packing/unpacking happens:

    This code:

    let packet = osc.writePacket(osc_msg, {metadata: true});
    let parsed = osc.readPacket(packet, {metadata: true});
    console.log('parsed.args[0].value=', parsed.args[0].value);

    resulted in:

    parsed.args[0].value= Uint8Array(6) [ 4, 4, 4, 4, 4, 4 ]
    

    So you might be able to work around the issue by receiving raw OSC data and reading it yourself, I'm not sure. I'll need to look into this further and expand the unit tests to including sending and receiving binary data over multiple transports.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions