node-osc 11.2.0 → 11.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/bump-version.yml +3 -3
- package/.github/workflows/create-release.yml +4 -4
- package/.github/workflows/nodejs.yml +4 -4
- package/README.md +3 -2
- package/agent.md +330 -0
- package/dist/lib/Client.js +1 -1
- package/dist/lib/Message.js +3 -1
- package/dist/lib/Server.js +7 -12
- package/dist/lib/internal/decode.js +3 -1
- package/dist/lib/osc.js +32 -3
- package/dist/test/lib/osc.js +32 -3
- package/dist/test/test-bundle.js +13 -12
- package/dist/test/test-client.js +68 -37
- package/dist/test/test-decode.js +35 -0
- package/dist/test/test-e2e.js +9 -9
- package/dist/test/test-encode-decode.js +455 -0
- package/dist/test/test-error-handling.js +14 -13
- package/dist/test/test-message.js +261 -64
- package/dist/test/test-osc-internal.js +151 -0
- package/dist/test/test-promises.js +90 -26
- package/dist/test/test-server.js +19 -16
- package/docs/README.md +81 -0
- package/examples/README.md +3 -1
- package/lib/Client.mjs +1 -1
- package/lib/Message.mjs +3 -1
- package/lib/Server.mjs +7 -12
- package/lib/internal/decode.mjs +3 -1
- package/lib/osc.mjs +32 -3
- package/package.json +2 -2
- package/rollup.config.mjs +1 -0
- package/test/test-bundle.mjs +14 -13
- package/test/test-client.mjs +69 -38
- package/test/test-decode.mjs +35 -0
- package/test/test-e2e.mjs +10 -10
- package/test/test-encode-decode.mjs +455 -0
- package/test/test-error-handling.mjs +15 -14
- package/test/test-message.mjs +262 -66
- package/test/test-osc-internal.mjs +151 -0
- package/test/test-promises.mjs +91 -27
- package/test/test-server.mjs +20 -17
- package/types/Message.d.mts.map +1 -1
- package/types/Server.d.mts.map +1 -1
- package/types/internal/decode.d.mts.map +1 -1
- package/types/osc.d.mts.map +1 -1
- package/dist/test/test-getPort.js +0 -20
- package/dist/test/util.js +0 -34
- package/test/test-getPort.mjs +0 -18
- package/test/util.mjs +0 -34
|
@@ -1,55 +1,69 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var node_events = require('node:events');
|
|
3
4
|
var tap = require('tap');
|
|
4
|
-
var util = require('./util.js');
|
|
5
5
|
var nodeOsc = require('node-osc');
|
|
6
6
|
|
|
7
7
|
function round(num) {
|
|
8
8
|
return Math.round(num * 100) / 100;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
tap.
|
|
11
|
+
tap.test('message: basic usage', async (t) => {
|
|
12
|
+
const server = new nodeOsc.Server(0, '127.0.0.1');
|
|
13
|
+
await node_events.once(server, 'listening');
|
|
14
|
+
const client = new nodeOsc.Client('127.0.0.1', server.port);
|
|
15
|
+
|
|
16
|
+
t.plan(1);
|
|
17
|
+
t.teardown(async () => {
|
|
18
|
+
await server.close();
|
|
19
|
+
await client.close();
|
|
20
|
+
});
|
|
12
21
|
|
|
13
|
-
tap.test('message: basic usage', (t) => {
|
|
14
|
-
const oscServer = new nodeOsc.Server(t.context.port, '127.0.0.1');
|
|
15
|
-
const client = new nodeOsc.Client('127.0.0.1', t.context.port);
|
|
16
22
|
const m = new nodeOsc.Message('/address');
|
|
17
23
|
m.append('testing');
|
|
18
24
|
m.append(123);
|
|
19
25
|
m.append([456, 789]);
|
|
20
26
|
|
|
21
|
-
|
|
27
|
+
server.on('message', (msg) => {
|
|
22
28
|
const expected = ['/address', 'testing', 123, 456, 789];
|
|
23
29
|
t.same(msg, expected, `We reveived the payload: ${msg}`);
|
|
24
|
-
oscServer.close();
|
|
25
|
-
t.end();
|
|
26
30
|
});
|
|
27
31
|
|
|
28
|
-
client.send(m
|
|
29
|
-
client.close();
|
|
30
|
-
});
|
|
32
|
+
client.send(m);
|
|
31
33
|
});
|
|
32
34
|
|
|
33
|
-
tap.test('message: multiple args', (t) => {
|
|
34
|
-
const
|
|
35
|
-
|
|
35
|
+
tap.test('message: multiple args', async (t) => {
|
|
36
|
+
const server = new nodeOsc.Server(0, '127.0.0.1');
|
|
37
|
+
await node_events.once(server, 'listening');
|
|
38
|
+
const client = new nodeOsc.Client('127.0.0.1', server.port);
|
|
39
|
+
|
|
40
|
+
t.plan(1);
|
|
41
|
+
t.teardown(async () => {
|
|
42
|
+
await server.close();
|
|
43
|
+
await client.close();
|
|
44
|
+
});
|
|
45
|
+
|
|
36
46
|
const m = new nodeOsc.Message('/address', 'testing', 123, true);
|
|
37
47
|
|
|
38
|
-
|
|
48
|
+
server.on('message', (msg) => {
|
|
39
49
|
const expected = ['/address', 'testing', 123, true];
|
|
40
50
|
t.same(msg, expected, `We reveived the payload: ${msg}`);
|
|
41
|
-
oscServer.close();
|
|
42
|
-
t.end();
|
|
43
51
|
});
|
|
44
52
|
|
|
45
|
-
client.send(m
|
|
46
|
-
client.close();
|
|
47
|
-
});
|
|
53
|
+
client.send(m);
|
|
48
54
|
});
|
|
49
55
|
|
|
50
|
-
tap.test('message: object', (t) => {
|
|
51
|
-
const
|
|
52
|
-
|
|
56
|
+
tap.test('message: object', async (t) => {
|
|
57
|
+
const server = new nodeOsc.Server(0, '127.0.0.1');
|
|
58
|
+
await node_events.once(server, 'listening');
|
|
59
|
+
const client = new nodeOsc.Client('127.0.0.1', server.port);
|
|
60
|
+
|
|
61
|
+
t.plan(1);
|
|
62
|
+
t.teardown(async () => {
|
|
63
|
+
await server.close();
|
|
64
|
+
await client.close();
|
|
65
|
+
});
|
|
66
|
+
|
|
53
67
|
const m = new nodeOsc.Message('/address');
|
|
54
68
|
m.append({
|
|
55
69
|
type: 'string',
|
|
@@ -60,43 +74,51 @@ tap.test('message: object', (t) => {
|
|
|
60
74
|
value: 100
|
|
61
75
|
});
|
|
62
76
|
|
|
63
|
-
|
|
77
|
+
server.on('message', (msg) => {
|
|
64
78
|
const expected = ['/address', 'test', 100];
|
|
65
79
|
t.same(msg, expected, `We reveived the payload: ${msg}`);
|
|
66
|
-
oscServer.close();
|
|
67
|
-
t.end();
|
|
68
80
|
});
|
|
69
81
|
|
|
70
|
-
client.send(m
|
|
71
|
-
client.close();
|
|
72
|
-
});
|
|
82
|
+
client.send(m);
|
|
73
83
|
});
|
|
74
84
|
|
|
75
|
-
tap.test('message: float', (t) => {
|
|
76
|
-
const
|
|
77
|
-
|
|
85
|
+
tap.test('message: float', async (t) => {
|
|
86
|
+
const server = new nodeOsc.Server(0, '127.0.0.1');
|
|
87
|
+
await node_events.once(server, 'listening');
|
|
88
|
+
const client = new nodeOsc.Client('127.0.0.1', server.port);
|
|
89
|
+
|
|
90
|
+
t.plan(2);
|
|
91
|
+
t.teardown(async () => {
|
|
92
|
+
await server.close();
|
|
93
|
+
await client.close();
|
|
94
|
+
});
|
|
95
|
+
|
|
78
96
|
const m = new nodeOsc.Message('/address');
|
|
79
97
|
m.append(3.14);
|
|
80
98
|
|
|
81
|
-
|
|
99
|
+
server.on('message', (msg) => {
|
|
82
100
|
const expected = [
|
|
83
101
|
'/address',
|
|
84
102
|
3.14
|
|
85
103
|
];
|
|
86
104
|
t.equal(msg[0], expected[0], `We reveived the payload: ${msg}`);
|
|
87
105
|
t.equal(round(msg[1]), expected[1], 'pie please');
|
|
88
|
-
oscServer.close();
|
|
89
|
-
t.end();
|
|
90
106
|
});
|
|
91
107
|
|
|
92
|
-
client.send(m
|
|
93
|
-
client.close();
|
|
94
|
-
});
|
|
108
|
+
client.send(m);
|
|
95
109
|
});
|
|
96
110
|
|
|
97
|
-
tap.test('message: alias messages', (t) => {
|
|
98
|
-
const
|
|
99
|
-
|
|
111
|
+
tap.test('message: alias messages', async (t) => {
|
|
112
|
+
const server = new nodeOsc.Server(0, '127.0.0.1');
|
|
113
|
+
await node_events.once(server, 'listening');
|
|
114
|
+
const client = new nodeOsc.Client('127.0.0.1', server.port);
|
|
115
|
+
|
|
116
|
+
t.plan(5);
|
|
117
|
+
t.teardown(async () => {
|
|
118
|
+
await server.close();
|
|
119
|
+
await client.close();
|
|
120
|
+
});
|
|
121
|
+
|
|
100
122
|
const m = new nodeOsc.Message('/address');
|
|
101
123
|
m.append({
|
|
102
124
|
type: 'i',
|
|
@@ -107,7 +129,7 @@ tap.test('message: alias messages', (t) => {
|
|
|
107
129
|
value: 3.14
|
|
108
130
|
});
|
|
109
131
|
|
|
110
|
-
|
|
132
|
+
server.on('message', (msg) => {
|
|
111
133
|
const expected = [
|
|
112
134
|
'/address',
|
|
113
135
|
123,
|
|
@@ -118,39 +140,47 @@ tap.test('message: alias messages', (t) => {
|
|
|
118
140
|
t.ok(Number.isInteger(msg[1]), 'the first value is an int');
|
|
119
141
|
t.equal(round(msg[2]), expected[2], 'pie please');
|
|
120
142
|
t.ok(msg[2] % 1 !== 0, 'the second value is a float');
|
|
121
|
-
oscServer.close();
|
|
122
|
-
t.end();
|
|
123
143
|
});
|
|
124
144
|
|
|
125
|
-
client.send(m
|
|
126
|
-
client.close();
|
|
127
|
-
});
|
|
145
|
+
client.send(m);
|
|
128
146
|
});
|
|
129
147
|
|
|
130
|
-
tap.test('message: boolean', (t) => {
|
|
131
|
-
const
|
|
132
|
-
|
|
148
|
+
tap.test('message: boolean', async (t) => {
|
|
149
|
+
const server = new nodeOsc.Server(0, '127.0.0.1');
|
|
150
|
+
await node_events.once(server, 'listening');
|
|
151
|
+
|
|
152
|
+
t.plan(1);
|
|
153
|
+
t.teardown(async () => {
|
|
154
|
+
await server.close();
|
|
155
|
+
await client.close();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const client = new nodeOsc.Client('127.0.0.1', server.port);
|
|
133
159
|
const m = new nodeOsc.Message('/address');
|
|
134
160
|
m.append(true);
|
|
135
161
|
|
|
136
|
-
|
|
162
|
+
server.on('message', (msg) => {
|
|
137
163
|
const expected = [
|
|
138
164
|
'/address',
|
|
139
165
|
true
|
|
140
166
|
];
|
|
141
167
|
t.same(msg, expected, `We reveived the payload: ${msg}`);
|
|
142
|
-
oscServer.close();
|
|
143
|
-
t.end();
|
|
144
168
|
});
|
|
145
169
|
|
|
146
|
-
client.send(m
|
|
147
|
-
client.close();
|
|
148
|
-
});
|
|
170
|
+
client.send(m);
|
|
149
171
|
});
|
|
150
172
|
|
|
151
|
-
tap.test('message: blob', (t) => {
|
|
152
|
-
const
|
|
153
|
-
|
|
173
|
+
tap.test('message: blob', async (t) => {
|
|
174
|
+
const server = new nodeOsc.Server(0, '127.0.0.1');
|
|
175
|
+
await node_events.once(server, 'listening');
|
|
176
|
+
const client = new nodeOsc.Client('127.0.0.1', server.port);
|
|
177
|
+
|
|
178
|
+
t.plan(1);
|
|
179
|
+
t.teardown(async () => {
|
|
180
|
+
await server.close();
|
|
181
|
+
await client.close();
|
|
182
|
+
});
|
|
183
|
+
|
|
154
184
|
const m = new nodeOsc.Message('/address');
|
|
155
185
|
const buf = Buffer.from('test');
|
|
156
186
|
m.append({
|
|
@@ -158,19 +188,42 @@ tap.test('message: blob', (t) => {
|
|
|
158
188
|
value: buf
|
|
159
189
|
});
|
|
160
190
|
|
|
161
|
-
|
|
191
|
+
server.on('message', (msg) => {
|
|
162
192
|
const expected = [
|
|
163
193
|
'/address',
|
|
164
194
|
buf
|
|
165
195
|
];
|
|
166
196
|
t.same(msg, expected, `We reveived the payload: ${msg}`);
|
|
167
|
-
oscServer.close();
|
|
168
|
-
t.end();
|
|
169
197
|
});
|
|
170
198
|
|
|
171
|
-
client.send(m
|
|
172
|
-
|
|
199
|
+
client.send(m);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
tap.test('message: Buffer as blob', async (t) => {
|
|
203
|
+
const server = new nodeOsc.Server(0, '127.0.0.1');
|
|
204
|
+
await node_events.once(server, 'listening');
|
|
205
|
+
const client = new nodeOsc.Client('127.0.0.1', server.port);
|
|
206
|
+
|
|
207
|
+
t.plan(1);
|
|
208
|
+
t.teardown(async () => {
|
|
209
|
+
await server.close();
|
|
210
|
+
await client.close();
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
const m = new nodeOsc.Message('/address');
|
|
214
|
+
const buf = Buffer.from('test buffer data');
|
|
215
|
+
// Directly append Buffer without wrapping in object
|
|
216
|
+
m.append(buf);
|
|
217
|
+
|
|
218
|
+
server.on('message', (msg) => {
|
|
219
|
+
const expected = [
|
|
220
|
+
'/address',
|
|
221
|
+
buf
|
|
222
|
+
];
|
|
223
|
+
t.same(msg, expected, `We received the buffer payload: ${msg}`);
|
|
173
224
|
});
|
|
225
|
+
|
|
226
|
+
client.send(m);
|
|
174
227
|
});
|
|
175
228
|
|
|
176
229
|
// test('message: timetag', (t) => {
|
|
@@ -192,6 +245,150 @@ tap.test('message: blob', (t) => {
|
|
|
192
245
|
// });
|
|
193
246
|
// });
|
|
194
247
|
|
|
248
|
+
tap.test('message: Buffer with multiple arguments', async (t) => {
|
|
249
|
+
const server = new nodeOsc.Server(0, '127.0.0.1');
|
|
250
|
+
await node_events.once(server, 'listening');
|
|
251
|
+
const client = new nodeOsc.Client('127.0.0.1', server.port);
|
|
252
|
+
|
|
253
|
+
t.plan(6);
|
|
254
|
+
t.teardown(async () => {
|
|
255
|
+
await server.close();
|
|
256
|
+
await client.close();
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
const m = new nodeOsc.Message('/address');
|
|
260
|
+
const buf1 = Buffer.from('first');
|
|
261
|
+
const buf2 = Buffer.from('second');
|
|
262
|
+
|
|
263
|
+
m.append('string');
|
|
264
|
+
m.append(42);
|
|
265
|
+
m.append(buf1);
|
|
266
|
+
m.append(3.14);
|
|
267
|
+
m.append(buf2);
|
|
268
|
+
|
|
269
|
+
server.on('message', (msg) => {
|
|
270
|
+
t.equal(msg[0], '/address', 'Address matches');
|
|
271
|
+
t.equal(msg[1], 'string', 'String matches');
|
|
272
|
+
t.equal(msg[2], 42, 'Integer matches');
|
|
273
|
+
t.same(msg[3], buf1, 'First buffer matches');
|
|
274
|
+
t.equal(round(msg[4]), 3.14, 'Float matches');
|
|
275
|
+
t.same(msg[5], buf2, 'Second buffer matches');
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
client.send(m);
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
tap.test('message: Buffer in constructor', async (t) => {
|
|
282
|
+
const server = new nodeOsc.Server(0, '127.0.0.1');
|
|
283
|
+
await node_events.once(server, 'listening');
|
|
284
|
+
const client = new nodeOsc.Client('127.0.0.1', server.port);
|
|
285
|
+
|
|
286
|
+
t.plan(1);
|
|
287
|
+
t.teardown(async () => {
|
|
288
|
+
await server.close();
|
|
289
|
+
await client.close();
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
const buf = Buffer.from('constructor buffer');
|
|
293
|
+
const m = new nodeOsc.Message('/address', 'test', buf, 123);
|
|
294
|
+
|
|
295
|
+
server.on('message', (msg) => {
|
|
296
|
+
const expected = [
|
|
297
|
+
'/address',
|
|
298
|
+
'test',
|
|
299
|
+
buf,
|
|
300
|
+
123
|
|
301
|
+
];
|
|
302
|
+
t.same(msg, expected, `We received the constructor buffer payload: ${msg}`);
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
client.send(m);
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
tap.test('message: Buffer in array', async (t) => {
|
|
309
|
+
const server = new nodeOsc.Server(0, '127.0.0.1');
|
|
310
|
+
await node_events.once(server, 'listening');
|
|
311
|
+
const client = new nodeOsc.Client('127.0.0.1', server.port);
|
|
312
|
+
|
|
313
|
+
t.plan(1);
|
|
314
|
+
t.teardown(async () => {
|
|
315
|
+
await server.close();
|
|
316
|
+
await client.close();
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
const m = new nodeOsc.Message('/address');
|
|
320
|
+
const buf1 = Buffer.from('array1');
|
|
321
|
+
const buf2 = Buffer.from('array2');
|
|
322
|
+
|
|
323
|
+
m.append([buf1, 'string', buf2, 456]);
|
|
324
|
+
|
|
325
|
+
server.on('message', (msg) => {
|
|
326
|
+
const expected = [
|
|
327
|
+
'/address',
|
|
328
|
+
buf1,
|
|
329
|
+
'string',
|
|
330
|
+
buf2,
|
|
331
|
+
456
|
|
332
|
+
];
|
|
333
|
+
t.same(msg, expected, `We received the array with buffers: ${msg}`);
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
client.send(m);
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
tap.test('message: empty Buffer', async (t) => {
|
|
340
|
+
const server = new nodeOsc.Server(0, '127.0.0.1');
|
|
341
|
+
await node_events.once(server, 'listening');
|
|
342
|
+
const client = new nodeOsc.Client('127.0.0.1', server.port);
|
|
343
|
+
|
|
344
|
+
t.plan(1);
|
|
345
|
+
t.teardown(async () => {
|
|
346
|
+
await server.close();
|
|
347
|
+
await client.close();
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
const m = new nodeOsc.Message('/address');
|
|
351
|
+
const buf = Buffer.from('');
|
|
352
|
+
|
|
353
|
+
m.append(buf);
|
|
354
|
+
|
|
355
|
+
server.on('message', (msg) => {
|
|
356
|
+
const expected = [
|
|
357
|
+
'/address',
|
|
358
|
+
buf
|
|
359
|
+
];
|
|
360
|
+
t.same(msg, expected, `We received the empty buffer: ${msg}`);
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
client.send(m);
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
tap.test('message: large Buffer', async (t) => {
|
|
367
|
+
const server = new nodeOsc.Server(0, '127.0.0.1');
|
|
368
|
+
await node_events.once(server, 'listening');
|
|
369
|
+
const client = new nodeOsc.Client('127.0.0.1', server.port);
|
|
370
|
+
|
|
371
|
+
t.plan(4);
|
|
372
|
+
t.teardown(async () => {
|
|
373
|
+
await server.close();
|
|
374
|
+
await client.close();
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
const m = new nodeOsc.Message('/address');
|
|
378
|
+
const buf = Buffer.alloc(1024, 'x');
|
|
379
|
+
|
|
380
|
+
m.append(buf);
|
|
381
|
+
|
|
382
|
+
server.on('message', (msg) => {
|
|
383
|
+
t.equal(msg[0], '/address', 'Address matches');
|
|
384
|
+
t.ok(Buffer.isBuffer(msg[1]), 'Second element is a Buffer');
|
|
385
|
+
t.equal(msg[1].length, 1024, 'Buffer size matches');
|
|
386
|
+
t.same(msg[1], buf, 'Buffer content matches');
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
client.send(m);
|
|
390
|
+
});
|
|
391
|
+
|
|
195
392
|
tap.test('message: error', (t) => {
|
|
196
393
|
const m = new nodeOsc.Message('/address');
|
|
197
394
|
t.plan(2);
|
|
@@ -25,6 +25,46 @@ tap.test('osc: timetag encoding with non-number value', (t) => {
|
|
|
25
25
|
t.end();
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
+
tap.test('osc: timetag encoding with zero value', (t) => {
|
|
29
|
+
const bundle = {
|
|
30
|
+
oscType: 'bundle',
|
|
31
|
+
timetag: 0,
|
|
32
|
+
elements: [
|
|
33
|
+
{
|
|
34
|
+
oscType: 'message',
|
|
35
|
+
address: '/test',
|
|
36
|
+
args: []
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const buffer = osc.encode(bundle);
|
|
42
|
+
const decoded = osc.decode(buffer);
|
|
43
|
+
|
|
44
|
+
t.equal(decoded.timetag, 0, 'should encode 0 as immediate execution');
|
|
45
|
+
t.end();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
tap.test('osc: timetag encoding with numeric epoch value', (t) => {
|
|
49
|
+
const bundle = {
|
|
50
|
+
oscType: 'bundle',
|
|
51
|
+
timetag: 42,
|
|
52
|
+
elements: [
|
|
53
|
+
{
|
|
54
|
+
oscType: 'message',
|
|
55
|
+
address: '/test',
|
|
56
|
+
args: []
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const buffer = osc.encode(bundle);
|
|
62
|
+
const decoded = osc.decode(buffer);
|
|
63
|
+
|
|
64
|
+
t.equal(decoded.timetag, 42, 'should preserve numeric timetag values');
|
|
65
|
+
t.end();
|
|
66
|
+
});
|
|
67
|
+
|
|
28
68
|
tap.test('osc: timetag with immediate execution values', (t) => {
|
|
29
69
|
// Test readTimeTag with seconds === 0 && fraction === 1
|
|
30
70
|
const bundle = {
|
|
@@ -767,6 +807,117 @@ tap.test('osc: explicit double type name', (t) => {
|
|
|
767
807
|
t.end();
|
|
768
808
|
});
|
|
769
809
|
|
|
810
|
+
tap.test('osc: malformed packet with missing string terminator', (t) => {
|
|
811
|
+
const buffer = Buffer.from('/test', 'utf8');
|
|
812
|
+
|
|
813
|
+
t.throws(() => {
|
|
814
|
+
osc.decode(buffer);
|
|
815
|
+
}, /Malformed Packet: Missing null terminator for string/, 'should throw on unterminated string');
|
|
816
|
+
t.end();
|
|
817
|
+
});
|
|
818
|
+
|
|
819
|
+
tap.test('osc: malformed packet with truncated int32 argument', (t) => {
|
|
820
|
+
const address = Buffer.from('/i\0\0', 'ascii');
|
|
821
|
+
const typeTags = Buffer.from(',i\0\0', 'ascii');
|
|
822
|
+
const truncated = Buffer.from([0x00, 0x01]);
|
|
823
|
+
const buffer = Buffer.concat([address, typeTags, truncated]);
|
|
824
|
+
|
|
825
|
+
t.throws(() => {
|
|
826
|
+
osc.decode(buffer);
|
|
827
|
+
}, /Malformed Packet: Not enough bytes for int32/, 'should throw on truncated int32');
|
|
828
|
+
t.end();
|
|
829
|
+
});
|
|
830
|
+
|
|
831
|
+
tap.test('osc: malformed packet with truncated float32 argument', (t) => {
|
|
832
|
+
const address = Buffer.from('/f\0\0', 'ascii');
|
|
833
|
+
const typeTags = Buffer.from(',f\0\0', 'ascii');
|
|
834
|
+
const truncated = Buffer.from([0x3f, 0x80, 0x00]);
|
|
835
|
+
const buffer = Buffer.concat([address, typeTags, truncated]);
|
|
836
|
+
|
|
837
|
+
t.throws(() => {
|
|
838
|
+
osc.decode(buffer);
|
|
839
|
+
}, /Malformed Packet: Not enough bytes for float32/, 'should throw on truncated float32');
|
|
840
|
+
t.end();
|
|
841
|
+
});
|
|
842
|
+
|
|
843
|
+
tap.test('osc: malformed packet with invalid blob length', (t) => {
|
|
844
|
+
const address = Buffer.from('/b\0\0', 'ascii');
|
|
845
|
+
const typeTags = Buffer.from(',b\0\0', 'ascii');
|
|
846
|
+
const length = Buffer.alloc(4);
|
|
847
|
+
length.writeInt32BE(-1, 0);
|
|
848
|
+
const buffer = Buffer.concat([address, typeTags, length]);
|
|
849
|
+
|
|
850
|
+
t.throws(() => {
|
|
851
|
+
osc.decode(buffer);
|
|
852
|
+
}, /Malformed Packet: Invalid blob length/, 'should throw on negative blob length');
|
|
853
|
+
t.end();
|
|
854
|
+
});
|
|
855
|
+
|
|
856
|
+
tap.test('osc: malformed packet with truncated blob data', (t) => {
|
|
857
|
+
const address = Buffer.from('/b\0\0', 'ascii');
|
|
858
|
+
const typeTags = Buffer.from(',b\0\0', 'ascii');
|
|
859
|
+
const length = Buffer.alloc(4);
|
|
860
|
+
length.writeInt32BE(4, 0);
|
|
861
|
+
const data = Buffer.from([0x01, 0x02]);
|
|
862
|
+
const buffer = Buffer.concat([address, typeTags, length, data]);
|
|
863
|
+
|
|
864
|
+
t.throws(() => {
|
|
865
|
+
osc.decode(buffer);
|
|
866
|
+
}, /Malformed Packet: Not enough bytes for blob/, 'should throw on truncated blob data');
|
|
867
|
+
t.end();
|
|
868
|
+
});
|
|
869
|
+
|
|
870
|
+
tap.test('osc: malformed packet with missing blob padding', (t) => {
|
|
871
|
+
const address = Buffer.from('/b\0\0', 'ascii');
|
|
872
|
+
const typeTags = Buffer.from(',b\0\0', 'ascii');
|
|
873
|
+
const length = Buffer.alloc(4);
|
|
874
|
+
length.writeInt32BE(3, 0);
|
|
875
|
+
const data = Buffer.from([0x01, 0x02, 0x03]);
|
|
876
|
+
const buffer = Buffer.concat([address, typeTags, length, data]);
|
|
877
|
+
|
|
878
|
+
t.throws(() => {
|
|
879
|
+
osc.decode(buffer);
|
|
880
|
+
}, /Malformed Packet: Not enough bytes for blob padding/, 'should throw on missing blob padding');
|
|
881
|
+
t.end();
|
|
882
|
+
});
|
|
883
|
+
|
|
884
|
+
tap.test('osc: malformed bundle with truncated timetag', (t) => {
|
|
885
|
+
const bundleHeader = Buffer.from('#bundle\0', 'ascii');
|
|
886
|
+
const timetag = Buffer.alloc(4);
|
|
887
|
+
const buffer = Buffer.concat([bundleHeader, timetag]);
|
|
888
|
+
|
|
889
|
+
t.throws(() => {
|
|
890
|
+
osc.decode(buffer);
|
|
891
|
+
}, /Malformed Packet: Not enough bytes for timetag/, 'should throw on truncated timetag');
|
|
892
|
+
t.end();
|
|
893
|
+
});
|
|
894
|
+
|
|
895
|
+
tap.test('osc: malformed bundle with invalid element size', (t) => {
|
|
896
|
+
const bundleHeader = Buffer.from('#bundle\0', 'ascii');
|
|
897
|
+
const timetag = Buffer.alloc(8);
|
|
898
|
+
const size = Buffer.alloc(4);
|
|
899
|
+
size.writeInt32BE(0, 0);
|
|
900
|
+
const buffer = Buffer.concat([bundleHeader, timetag, size]);
|
|
901
|
+
|
|
902
|
+
t.throws(() => {
|
|
903
|
+
osc.decode(buffer);
|
|
904
|
+
}, /Malformed Packet/, 'should throw on invalid bundle element size');
|
|
905
|
+
t.end();
|
|
906
|
+
});
|
|
907
|
+
|
|
908
|
+
tap.test('osc: malformed bundle with oversized element size', (t) => {
|
|
909
|
+
const bundleHeader = Buffer.from('#bundle\0', 'ascii');
|
|
910
|
+
const timetag = Buffer.alloc(8);
|
|
911
|
+
const size = Buffer.alloc(4);
|
|
912
|
+
size.writeInt32BE(12, 0);
|
|
913
|
+
const buffer = Buffer.concat([bundleHeader, timetag, size, Buffer.from([0x01, 0x02])]);
|
|
914
|
+
|
|
915
|
+
t.throws(() => {
|
|
916
|
+
osc.decode(buffer);
|
|
917
|
+
}, /Malformed Packet/, 'should throw on oversized bundle element size');
|
|
918
|
+
t.end();
|
|
919
|
+
});
|
|
920
|
+
|
|
770
921
|
tap.test('osc: blob padding when length is multiple of 4', (t) => {
|
|
771
922
|
// Test writeBlob line 52: padding === 4 branch (should use 0)
|
|
772
923
|
const message = {
|