summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pb_decode.c20
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