0

Following this question, I decided to serialise some data I need to send over a TCP/IP connection.

The data is pretty simple :

typedef struct whiteboard {
    int palladium, platine, zirconium, erbium, astate, californium;
} sharedData;

And my serialisation function is pretty simple as well :

void serializeWhiteboard (sharedData* message, char** packet) {
    int* r = (int*) packet;
    *r = (int)VALUE_FROM_ENUM; // just some enum to get the type of message sent
    r++;
    char* q = (char*) r;
    *q = '/'; q++; // delimitors for parsing
    *q = '/'; q++; // the message on the other end
    int* p = (int*) q;
    *p = message->palladium;    p++;
    *p = message->platine;      p++;
    *p = message->zirconium;    p++;
    *p = message->erbium;       p++;
    *p = message->astate;       p++;
    *p = message->californium;  p++;
    return;
}

In my calling program, I have the following code :

int main() {
    sharedData data = {0};
    // define the data values ...
    char* dest = malloc(sizeof(int) + 2*sizeof(char) + 6*sizeof(int));
    serialiseWhiteboard(&data, &dest);
    // And here, the first two fields of 'data' have changed
    // as if by magic, since I do not touch the fields in 
    // serializeWhiteboard() .
    return 0;
 }

I cannot for the life of me figure out why the first two fields of data would change when I just read the values from it. And yet with some print values I was able to track it down to the second-to-last line in serializeWhiteboard(), just before the return;, which doesn't make any sense. The data is fine until right before the call to return.

Did anyone encounter such a problem before ?

  • 2
    There is zero need to pass `dest` by address to that function. It makes no sense at all. `dest` points to the buffer you want to serialize to. It should require no modifications. The address it holds should be passed by-value (single indirection) to a `char*` argument. and all of the `*p = ...` should be reworked to reflect said-same. You'll may also hit value-boundaries on your conversion from `int` to `*`, btw. – WhozCraig Dec 09 '18 at 00:58
  • I'm C, 9 times out of 10, if you're casting a pointer, you're wrong. Maybe only 4 times out of 10 if you're casting to `(char *)` – torstenvl Dec 09 '18 at 01:04

1 Answers1

3

You have char** packet which is a pointer to a pointer to some chars.

You then treat that as int * which is a pointer to some ints.

You then overwrite the first int - so you're writing into 'dest' itself and not what it points to. And since you write more after that, you're corrupting the stack.