Skip to content

Commit

Permalink
Fixes #138: Allow creating size-0 blobs
Browse files Browse the repository at this point in the history
  • Loading branch information
JohannesLorenz committed Jan 13, 2024
1 parent ed21c61 commit b0a22d4
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 17 deletions.
2 changes: 2 additions & 0 deletions lo/lo.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ uint32_t lo_blob_datasize(lo_blob b);
/**
* \brief Return a pointer to the start of the blob data to allow contents to
* be changed.
*
* If the size is 0, this will return a NULL-pointer.
*/
void *lo_blob_dataptr(lo_blob b);

Expand Down
8 changes: 5 additions & 3 deletions src/blob.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ lo_blob lo_blob_new(int32_t size, const void *data)
{
lo_blob b;

if (size < 1) {
if (size < 0) {
return NULL;
}

b = (lo_blob) malloc(sizeof(size) + size);

b->size = size;

if (data) {
if (size && data) {
memcpy((char*) b + sizeof(uint32_t), data, size);
}

Expand All @@ -51,7 +51,9 @@ uint32_t lo_blob_datasize(lo_blob b)

void *lo_blob_dataptr(lo_blob b)
{
return (char*) b + sizeof(uint32_t);
return b->size
? (char*) b + sizeof(uint32_t)
: NULL;
}

uint32_t lo_blobsize(lo_blob b)
Expand Down
64 changes: 50 additions & 14 deletions src/testlo.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,10 @@ int lots_handler(const char *path, const char *types, lo_arg ** argv,
TEST(types[12] == 'F');
TEST(types[13] == 'N');
TEST(types[14] == 'I');
b = (lo_blob) argv[15];
d = (unsigned char *) lo_blob_dataptr(b);
TEST(types[15] == 'b' && lo_blob_datasize(b) == 0);
TEST(d == NULL);

printf("\n");

Expand Down Expand Up @@ -538,13 +542,14 @@ void test_deserialise()
char data[256];
int result = 0;

lo_blob btest;
lo_blob btest, btest_empty;
lo_timetag tt = { 0x1, 0x80000000 };
lo_blob b = NULL;

DOING("test_deserialise");

btest = lo_blob_new(sizeof(testdata), testdata);
btest_empty = lo_blob_new(0, NULL);

// build a message
lo_message msg = lo_message_new();
Expand All @@ -564,9 +569,10 @@ void test_deserialise()
lo_message_add_false(msg); // 12 F
lo_message_add_nil(msg); // 13 N
lo_message_add_infinitum(msg); // 14 I
lo_message_add_blob(msg, btest_empty); // 15 b

// test types, args
TEST(15 == lo_message_get_argc(msg));
TEST(16 == lo_message_get_argc(msg));
types = lo_message_get_types(msg);
TEST(NULL != types);
argv = lo_message_get_argv(msg);
Expand All @@ -591,14 +597,19 @@ void test_deserialise()
TEST('F' == types[12] && NULL == argv[12]);
TEST('N' == types[13] && NULL == argv[13]);
TEST('I' == types[14] && NULL == argv[14]);
TEST('b' == types[15]);
b = (lo_blob) argv[15];
TEST(lo_blob_datasize(b) == 0);
TEST(4 == lo_blobsize(b));
TEST(lo_blob_dataptr(b) == NULL);

// serialise it
len = lo_message_length(msg, "/foo");
printf("serialise message_length=%d\n", (int) len);
buf = (char*) calloc(len, sizeof(char));
size = 0;
tmp = (char*) lo_message_serialise(msg, "/foo", buf, &size);
TEST(tmp == buf && size == len && 92 == len);
TEST(tmp == buf && size == len && 96 == len);
lo_message_free(msg);

// deserialise it
Expand All @@ -609,7 +620,7 @@ void test_deserialise()
TEST(NULL != msg);

// repeat same test as above
TEST(15 == lo_message_get_argc(msg));
TEST(16 == lo_message_get_argc(msg));
types = lo_message_get_types(msg);
TEST(NULL != types);
argv = lo_message_get_argv(msg);
Expand All @@ -634,17 +645,22 @@ void test_deserialise()
TEST('F' == types[12] && NULL == argv[12]);
TEST('N' == types[13] && NULL == argv[13]);
TEST('I' == types[14] && NULL == argv[14]);
b = (lo_blob) argv[15];
TEST(lo_blob_datasize(b) == 0);
TEST(4 == lo_blobsize(b));
TEST(lo_blob_dataptr(b) == NULL);

// serialise it again, compare
len = lo_message_length(msg, "/foo");
printf("serialise message_length=%d\n", (int) len);
buf2 = (char*) calloc(len, sizeof(char));
size = 0;
tmp = (char*) lo_message_serialise(msg, "/foo", buf2, &size);
TEST(tmp == buf2 && size == len && 92 == len);
TEST(tmp == buf2 && size == len && 96 == len);
TEST(!memcmp(buf, buf2, len));
lo_message_free(msg);

lo_blob_free(btest_empty);
lo_blob_free(btest);
free(buf);
free(buf2);
Expand Down Expand Up @@ -1240,19 +1256,36 @@ void test_blob()
}

lo_blob_free(btest);

/* Same for the empty blob */

lo_blob btest_empty;

btest_empty = lo_blob_new(0, NULL);

if (lo_blob_datasize(btest_empty) != 0 || lo_blobsize(btest_empty) != 4) {
printf("blob is %d (%d) bytes long, should be 0 (4)\n",
lo_blob_datasize(btest_empty), lo_blobsize(btest_empty));
lo_arg_pp(LO_BLOB, btest_empty);
printf(" <- blob\n");
exit(1);
}

lo_blob_free(btest_empty);
}

void test_server_thread(lo_server_thread *pst, lo_address *pa)
{
lo_address a;
char *server_url;
lo_server_thread st, sta, stb;
lo_blob btest;
lo_blob btest, btest_empty;
lo_timetag tt = { 0x1, 0x80000000 };

DOING("test_server_thread");

btest = lo_blob_new(sizeof(testdata), testdata);
btest_empty = lo_blob_new(0, NULL);

sta = lo_server_thread_new("7591", error);
stb = lo_server_thread_new("7591", rep_error);
Expand Down Expand Up @@ -1297,7 +1330,7 @@ void test_server_thread(lo_server_thread *pst, lo_address *pa)

lo_server_thread_add_method(st, "/reply", "s", reply_handler, NULL);

lo_server_thread_add_method(st, "/lotsofformats", "fisbmhtdSccTFNI",
lo_server_thread_add_method(st, "/lotsofformats", "fisbmhtdSccTFNIb",
lots_handler, NULL);

lo_server_thread_add_method(st, "/coerce", "dfhiSs",
Expand Down Expand Up @@ -1352,9 +1385,9 @@ void test_server_thread(lo_server_thread *pst, lo_address *pa)
#ifndef _MSC_VER /* MS compiler refuses to compile this case */
lo_send(a, "/bar", "ff", 0.12345678f, 1.0 / 0.0);
#endif
lo_send(a, "/lotsofformats", "fisbmhtdSccTFNI", 0.12345678f, 123,
lo_send(a, "/lotsofformats", "fisbmhtdSccTFNIb", 0.12345678f, 123,
"123", btest, midi_data, 0x0123456789abcdefULL, tt, 0.9999,
"sym", 'X', 'Y');
"sym", 'X', 'Y', btest_empty);
lo_send(a, "/coerce", "fdihsS", 0.1f, 0.2, 123, 124LL, "aaa", "bbb");
lo_send(a, "/coerce", "ffffss", 0.1f, 0.2f, 123.0, 124.0, "aaa",
"bbb");
Expand All @@ -1381,6 +1414,7 @@ void test_server_thread(lo_server_thread *pst, lo_address *pa)
lo_server_free(s);
}

lo_blob_free(btest_empty);
lo_blob_free(btest);

*pst = st;
Expand All @@ -1389,18 +1423,19 @@ void test_server_thread(lo_server_thread *pst, lo_address *pa)

void test_message(lo_address a)
{
lo_blob btest;
lo_blob btest, btest_empty;
lo_timetag tt = { 0x1, 0x80000000 };
lo_message m;

DOING("test_message");

btest = lo_blob_new(sizeof(testdata), testdata);
btest_empty = lo_blob_new(0, NULL);

TEST(test_varargs
(a, "/lotsofformats", "fisbmhtdSccTFNI", 0.12345678f, 123, "123",
(a, "/lotsofformats", "fisbmhtdSccTFNIb", 0.12345678f, 123, "123",
btest, midi_data, 0x0123456789abcdefULL, tt, 0.9999, "sym", 'X',
'Y', LO_ARGS_END) == 0);
'Y', btest_empty, LO_ARGS_END) == 0);

#ifdef __GNUC__
#ifndef USE_ANSI_C
Expand All @@ -1421,13 +1456,14 @@ void test_message(lo_address a)

// test lo_message_add
m = lo_message_new();
TEST(lo_message_add(m, "fisbmhtdSccTFNI", 0.12345678f, 123, "123",
TEST(lo_message_add(m, "fisbmhtdSccTFNIb", 0.12345678f, 123, "123",
btest, midi_data, 0x0123456789abcdefULL, tt,
0.9999, "sym", 'X', 'Y') == 0);
0.9999, "sym", 'X', 'Y', btest_empty) == 0);

lo_send_message(a, "/lotsofformats", m);

lo_message_free(m);
lo_blob_free(btest_empty);
lo_blob_free(btest);
}

Expand Down

0 comments on commit b0a22d4

Please sign in to comment.