diff options
Diffstat (limited to 'pb_decode.c')
-rw-r--r-- | pb_decode.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/pb_decode.c b/pb_decode.c index 37f30707..d1efd1b5 100644 --- a/pb_decode.c +++ b/pb_decode.c @@ -1072,32 +1072,35 @@ 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) { uint32_t size; + size_t alloc_size; pb_bytes_array_t *bdest; if (!pb_decode_varint32(stream, &size)) return false; + if (size > PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "bytes overflow"); + + alloc_size = PB_BYTES_ARRAY_T_ALLOCSIZE(size); + if (size > alloc_size) + PB_RETURN_ERROR(stream, "size too large"); + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) { #ifndef PB_ENABLE_MALLOC PB_RETURN_ERROR(stream, "no malloc support"); #else - if (!allocate_field(stream, dest, PB_BYTES_ARRAY_T_ALLOCSIZE(size), 1)) + if (!allocate_field(stream, dest, alloc_size, 1)) return false; bdest = *(pb_bytes_array_t**)dest; #endif } else { - if (PB_BYTES_ARRAY_T_ALLOCSIZE(size) > field->data_size) + if (alloc_size > field->data_size) PB_RETURN_ERROR(stream, "bytes overflow"); bdest = (pb_bytes_array_t*)dest; } - - if (size > PB_SIZE_MAX) - { - PB_RETURN_ERROR(stream, "bytes overflow"); - } bdest->size = (pb_size_t)size; return pb_read(stream, bdest->bytes, size); @@ -1114,6 +1117,9 @@ static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *fi /* Space for null terminator */ alloc_size = size + 1; + if (alloc_size < size) + PB_RETURN_ERROR(stream, "size too large"); + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) { #ifndef PB_ENABLE_MALLOC |