Avoid overflows in allocation for packed fields.
This will only occur with unlimited length streams, so it's kind-of
low impact. Such streams allow denial of service anyway.
diff --git a/pb_decode.c b/pb_decode.c
index f16837b..f936412 100644
--- a/pb_decode.c
+++ b/pb_decode.c
@@ -670,12 +670,25 @@
while (substream.bytes_left)
{
+ if (*size == PB_SIZE_MAX)
+ {
+#ifndef PB_NO_ERRMSG
+ stream->errmsg = "too many array entries";
+#endif
+ status = false;
+ break;
+ }
+
if ((size_t)*size + 1 > allocated_size)
{
/* Allocate more storage. This tries to guess the
* number of remaining entries. Round the division
* upwards. */
- allocated_size += (substream.bytes_left - 1) / field->data_size + 1;
+ size_t remain = (substream.bytes_left - 1) / field->data_size + 1;
+ if (remain < PB_SIZE_MAX - allocated_size)
+ allocated_size += remain;
+ else
+ allocated_size += 1;
if (!allocate_field(&substream, field->pField, field->data_size, allocated_size))
{
@@ -693,15 +706,6 @@
break;
}
- if (*size == PB_SIZE_MAX)
- {
-#ifndef PB_NO_ERRMSG
- stream->errmsg = "too many array entries";
-#endif
- status = false;
- break;
- }
-
(*size)++;
}
if (!pb_close_string_substream(stream, &substream))