Add just-to-be-sure check to allocate_field().
This check will help to detect bugs earlier, and is quite lightweight compared to malloc() anyway.
This commit is contained in:
@@ -45,6 +45,7 @@ static bool checkreturn pb_skip_varint(pb_istream_t *stream);
|
|||||||
static bool checkreturn pb_skip_string(pb_istream_t *stream);
|
static bool checkreturn pb_skip_string(pb_istream_t *stream);
|
||||||
|
|
||||||
#ifdef PB_ENABLE_MALLOC
|
#ifdef PB_ENABLE_MALLOC
|
||||||
|
static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size);
|
||||||
static void pb_release_single_field(const pb_field_iter_t *iter);
|
static void pb_release_single_field(const pb_field_iter_t *iter);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -404,11 +405,15 @@ static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t
|
|||||||
{
|
{
|
||||||
void *ptr = *(void**)pData;
|
void *ptr = *(void**)pData;
|
||||||
|
|
||||||
|
if (data_size == 0 || array_size == 0)
|
||||||
|
PB_RETURN_ERROR(stream, "invalid size");
|
||||||
|
|
||||||
/* Check for multiplication overflows.
|
/* Check for multiplication overflows.
|
||||||
* This code avoids the costly division if the sizes are small enough.
|
* This code avoids the costly division if the sizes are small enough.
|
||||||
* Multiplication is safe as long as only half of bits are set
|
* Multiplication is safe as long as only half of bits are set
|
||||||
* in either multiplicand.
|
* in either multiplicand.
|
||||||
*/
|
*/
|
||||||
|
{
|
||||||
const size_t check_limit = (size_t)1 << (sizeof(size_t) * 4);
|
const size_t check_limit = (size_t)1 << (sizeof(size_t) * 4);
|
||||||
if (data_size >= check_limit || array_size >= check_limit)
|
if (data_size >= check_limit || array_size >= check_limit)
|
||||||
{
|
{
|
||||||
@@ -418,6 +423,7 @@ static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t
|
|||||||
PB_RETURN_ERROR(stream, "size too large");
|
PB_RETURN_ERROR(stream, "size too large");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate new or expand previous allocation */
|
/* Allocate new or expand previous allocation */
|
||||||
/* Note: on failure the old pointer will remain in the structure,
|
/* Note: on failure the old pointer will remain in the structure,
|
||||||
|
|||||||
Reference in New Issue
Block a user