X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=pb_decode.c;h=4e1872560c63b0509351c480273ad4f7ed054a7c;hb=0150b98be60b1e123fa51c561a908c234b6379fe;hp=d687cee384a8dcfd92e405185059b2c8dd57c690;hpb=5ef128616baffd15bb904fc56f651d40901be429;p=apps%2Fagl-service-can-low-level.git diff --git a/pb_decode.c b/pb_decode.c index d687cee3..4e187256 100644 --- a/pb_decode.c +++ b/pb_decode.c @@ -471,35 +471,31 @@ static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t #ifdef PB_ENABLE_MALLOC /* Allocate storage for the field and store the pointer at iter->pData. * array_size is the number of entries to reserve in an array. + * Zero size is not allowed, use pb_free() for releasing. */ static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size) { void *ptr = *(void**)pData; - /* Check for multiplication overflows. */ - size_t size = 0; - if (data_size > 0 && array_size > 0) + /* Check for multiplication overflows. + * This code avoids the costly division if the sizes are small enough. + * Multiplication is safe as long as only half of bits are set + * in either multiplicand. + */ + const size_t check_limit = (size_t)1 << (sizeof(size_t) * 4); + if (data_size >= check_limit || array_size >= check_limit) { - /* Avoid the costly division if the sizes are small enough. - * Multiplication is safe as long as only half of bits are set - * in either multiplicand. - */ - const size_t check_limit = (size_t)1 << (sizeof(size_t) * 4); - if (data_size >= check_limit || array_size >= check_limit) + const size_t size_max = (size_t)-1; + if (size_max / array_size < data_size) { - if (SIZE_MAX / array_size < data_size) - { - PB_RETURN_ERROR(stream, "size too large"); - } + PB_RETURN_ERROR(stream, "size too large"); } - - size = array_size * data_size; } /* Allocate new or expand previous allocation */ /* Note: on failure the old pointer will remain in the structure, * the message must be freed by caller also on error return. */ - ptr = pb_realloc(ptr, size); + ptr = pb_realloc(ptr, array_size * data_size); if (ptr == NULL) PB_RETURN_ERROR(stream, "realloc failed");