2

I'm trying to write a small plugin for X-Plane, to create a simple websocket server with libwebsocket. I'm able to connect to the websocket from Google Chrome, however, when I send data to the server, X-Plane immediately crashes.

I'm pretty certain the following code is causing the problem:

unsigned char *buf = (unsigned char*) malloc(LWS_SEND_BUFFER_PRE_PADDING + 13 + LWS_SEND_BUFFER_POST_PADDING);
buf = (unsigned char*) "Hello World!";
libwebsocket_write(wsi, buf, len, LWS_WRITE_TEXT);
free(buf);

I'm not a C programmer / specialist at all, but does the above seem to have a problem at all?

I've posted the full source on Gist: https://gist.github.com/josefvanniekerk/868432986f2f963a5583

josef.van.niekerk
  • 11,941
  • 20
  • 97
  • 157

2 Answers2

4

With any sane interface, @iharob would be right - to be clear he/she is right about you misunderstanding string assignment.

However, libwebsockets is a bit 'special'. You need to copy the string into the malloc()'d array LWS_SEND_BUFFER_PRE_PADDING bytes in. libwebsockets then overwrites the preceding bytes.

So you want something like (assuming you are not trying to send the terminating zero on the string):

char *text = "Hello World!";
int len = strlen (text);
unsigned char *buf = malloc(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING);
/* copy string but not terminating NUL */
memcpy (buf + LWS_SEND_BUFFER_PRE_PADDING, text, len );
libwebsocket_write(wsi, buf + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);
free(buf);

If you want to send the NUL as well:

char *text = "Hello World!";
int len = strlen (text) + 1;
unsigned char *buf = malloc(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING);
/* copy string including terminating NUL */
memcpy (buf + LWS_SEND_BUFFER_PRE_PADDING, text, len );
libwebsocket_write(wsi, buf + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);
free(buf);
abligh
  • 24,573
  • 4
  • 47
  • 84
1

You need to copy the string, assignment doesn't work as you expect.

Instead of

buf = (unsigned char *)"Hello World";

you need

memcpy(buf, "Hello World", 1 + strlen("Hello World"));

when you do the assignment, you make buf point to a static string literal, and free() is not possible in this case.

Your program invokes undefined behavior because of that.

You need to include <string.h>

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
  • 1
    I'm afraid you are not quite right there @iharob. libwebsockets is weird. You need to give it a buffer where it is guaranteed it can write to the prepadding. See my answer. – abligh Feb 03 '15 at 22:18
  • This `unsigned char *buf = (unsigned char*) malloc(LWS_SEND_BUFFER_PRE_PADDING + 13 + LWS_SEND_BUFFER_POST_PADDING); buf = (unsigned char*) "Hello World!";` is wrong it doesn't matter what! But I see your point. – Iharob Al Asimi Feb 03 '15 at 22:22
  • At the least, the memcpy() is not causing X-Plane to crash anymore, a tiny bit of progress. Not getting the right data on the browser however, although, getting some kind of response from the websocket server now. Maybe this is where the "special" bit of libwebsocket comes in. – josef.van.niekerk Feb 03 '15 at 22:24
  • 1
    Yes. I've made it clear in my answer that what you wrote is right re string assignment, but doesn't quite overcome the weirdness of libwebsockets. On the other hand, libwebsockets does actually work ... – abligh Feb 03 '15 at 22:24