X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=pb_encode.c;h=2e740347f0b155556fc1fe25b24e698081f071c9;hb=7f53c3f7484679c1e38607f59542d43be1387650;hp=63ca2889d9d2a4c9968d9e8d90b99ac3dd9b8da6;hpb=0c5bc4caf9cfb221822fead442b462be2f47b97b;p=apps%2Fagl-service-can-low-level.git diff --git a/pb_encode.c b/pb_encode.c index 63ca2889..2e740347 100644 --- a/pb_encode.c +++ b/pb_encode.c @@ -124,12 +124,17 @@ bool pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_ const pb_field_t *field = fields; const void *pData = src_struct; const void *pSize; + size_t prev_size = 0; while (field->tag != 0) { - pData = (const char*)pData + field->data_offset; + pData = (const char*)pData + prev_size + field->data_offset; pSize = (const char*)pData + field->size_offset; + prev_size = field->data_size; + if (PB_HTYPE(field->type) == PB_HTYPE_ARRAY) + prev_size *= field->array_size; + pb_encoder_t func = PB_ENCODERS[PB_LTYPE(field->type)]; switch (PB_HTYPE(field->type)) @@ -309,16 +314,17 @@ bool pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *sr bool pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src) { - pb_ostream_t sizestream = {0}; + pb_ostream_t substream = {0}; size_t size; + bool status; if (field->ptr == NULL) return false; - if (!pb_encode(&sizestream, (pb_field_t*)field->ptr, src)) + if (!pb_encode(&substream, (pb_field_t*)field->ptr, src)) return false; - size = sizestream.bytes_written; + size = substream.bytes_written; if (!pb_encode_varint(stream, size)) return false; @@ -326,6 +332,23 @@ bool pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void if (stream->callback == NULL) return pb_write(stream, NULL, size); /* Just sizing */ - return pb_encode(stream, (pb_field_t*)field->ptr, src); + if (stream->bytes_written + size > stream->max_size) + return false; + + /* Use a substream to verify that a callback doesn't write more than + * what it did the first time. */ + substream.callback = stream->callback; + substream.state = stream->state; + substream.max_size = size; + substream.bytes_written = 0; + + status = pb_encode(&substream, (pb_field_t*)field->ptr, src); + + stream->bytes_written += substream.bytes_written; + + if (substream.bytes_written != size) + return false; + + return status; }