X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=pb_decode.c;h=a8cd61a77bbddd72f3e2c5ac1c1a699a87aa0a70;hb=019d7bf948fc0d14b310fa397948ac550858af77;hp=b2a3a310be6643ce75b7e95f9caec10e0df9393a;hpb=58af4d1fb733c5348b68dd3980f2a230d95400b4;p=apps%2Fagl-service-can-low-level.git diff --git a/pb_decode.c b/pb_decode.c index b2a3a310..a8cd61a7 100644 --- a/pb_decode.c +++ b/pb_decode.c @@ -24,7 +24,6 @@ typedef bool (*pb_decoder_t)(pb_istream_t *stream, const pb_field_t *field, void *dest) checkreturn; static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); -static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest); static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size); static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); @@ -43,6 +42,7 @@ static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *f static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest); static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest); static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest); static bool checkreturn pb_skip_varint(pb_istream_t *stream); static bool checkreturn pb_skip_string(pb_istream_t *stream); @@ -66,7 +66,7 @@ static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = { &pb_dec_string, &pb_dec_submessage, NULL, /* extensions */ - &pb_dec_bytes /* PB_LTYPE_FIXED_LENGTH_BYTES */ + &pb_dec_fixed_length_bytes }; /******************************* @@ -170,7 +170,7 @@ pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize) * Helper functions * ********************/ -static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) +bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) { pb_byte_t byte; uint32_t result; @@ -334,13 +334,19 @@ bool checkreturn pb_make_string_substream(pb_istream_t *stream, pb_istream_t *su return true; } -void pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream) +bool checkreturn pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream) { + if (substream->bytes_left) { + if (!pb_read(substream, NULL, substream->bytes_left)) + return false; + } + stream->state = substream->state; #ifndef PB_NO_ERRMSG stream->errmsg = substream->errmsg; #endif + return true; } /************************* @@ -386,11 +392,12 @@ static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t } (*size)++; } - pb_close_string_substream(stream, &substream); - + if (substream.bytes_left != 0) PB_RETURN_ERROR(stream, "array overflow"); - + if (!pb_close_string_substream(stream, &substream)) + return false; + return status; } else @@ -570,7 +577,8 @@ static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_ (*size)++; } - pb_close_string_substream(stream, &substream); + if (!pb_close_string_substream(stream, &substream)) + return false; return status; } @@ -624,7 +632,9 @@ static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type PB_RETURN_ERROR(stream, "callback failed"); } while (substream.bytes_left); - pb_close_string_substream(stream, &substream); + if (!pb_close_string_substream(stream, &substream)) + return false; + return true; } else @@ -965,7 +975,9 @@ bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void * return false; status = pb_decode(&substream, fields, dest_struct); - pb_close_string_substream(stream, &substream); + + if (!pb_close_string_substream(stream, &substream)) + return false; return status; } @@ -1275,12 +1287,6 @@ static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *fie } else { - if (PB_LTYPE(field->type) == PB_LTYPE_FIXED_LENGTH_BYTES) { - if (size != field->data_size) - PB_RETURN_ERROR(stream, "incorrect inline bytes size"); - return pb_read(stream, (pb_byte_t*)dest, field->data_size); - } - if (alloc_size > field->data_size) PB_RETURN_ERROR(stream, "bytes overflow"); bdest = (pb_bytes_array_t*)dest; @@ -1344,6 +1350,30 @@ static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t else status = pb_decode_noinit(&substream, submsg_fields, dest); - pb_close_string_substream(stream, &substream); + if (!pb_close_string_substream(stream, &substream)) + return false; return status; } + +static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + uint32_t size; + + if (!pb_decode_varint32(stream, &size)) + return false; + + if (size > PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "bytes overflow"); + + if (size == 0) + { + /* As a special case, treat empty bytes string as all zeros for fixed_length_bytes. */ + memset(dest, 0, field->data_size); + return true; + } + + if (size != field->data_size) + PB_RETURN_ERROR(stream, "incorrect fixed length bytes size"); + + return pb_read(stream, (pb_byte_t*)dest, field->data_size); +}