summaryrefslogtreecommitdiffstats
path: root/pb_decode.c
diff options
context:
space:
mode:
authorPetteri Aimonen <jpa@git.mail.kapsi.fi>2014-02-25 19:58:11 +0200
committerPetteri Aimonen <jpa@git.mail.kapsi.fi>2014-02-25 19:58:11 +0200
commit48ac4613724ef0bfb7b0db61871127575b1d9002 (patch)
treedfc3e4ef4f92b02a36f922de77fddba62a072522 /pb_decode.c
parent011a30af9c015b1edd67420d9ca947e9fb499e73 (diff)
Bugfixes for dynamic allocation
Diffstat (limited to 'pb_decode.c')
-rw-r--r--pb_decode.c52
1 files changed, 39 insertions, 13 deletions
diff --git a/pb_decode.c b/pb_decode.c
index 4411e26a..30c36b36 100644
--- a/pb_decode.c
+++ b/pb_decode.c
@@ -359,6 +359,10 @@ static bool pb_field_next(pb_field_iterator_t *iter)
{
prev_size *= iter->pos->array_size;
}
+ else if (PB_ATYPE(iter->pos->type) == PB_ATYPE_POINTER)
+ {
+ prev_size = sizeof(void*);
+ }
if (iter->pos->tag == 0)
return false; /* Only happens with empty message types */
@@ -512,9 +516,17 @@ static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_
{
case PB_HTYPE_REQUIRED:
case PB_HTYPE_OPTIONAL:
- if (!allocate_field(stream, iter, 1))
- return false;
- return func(stream, iter->pos, iter->pData);
+ if (PB_LTYPE(type) == PB_LTYPE_STRING)
+ {
+ return func(stream, iter->pos, iter->pData);
+ }
+ else
+ {
+ if (!allocate_field(stream, iter, 1))
+ return false;
+
+ return func(stream, iter->pos, *(void**)iter->pData);
+ }
case PB_HTYPE_REPEATED:
if (wire_type == PB_WT_STRING
@@ -545,16 +557,16 @@ static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_
status = false;
break;
}
+ }
- /* Decode the array entry */
- pItem = (uint8_t*)iter->pData + iter->pos->data_size * (*size);
- if (!func(&substream, iter->pos, pItem))
- {
- status = false;
- break;
- }
- (*size)++;
+ /* Decode the array entry */
+ pItem = (uint8_t*)iter->pData + iter->pos->data_size * (*size);
+ if (!func(&substream, iter->pos, pItem))
+ {
+ status = false;
+ break;
}
+ (*size)++;
}
pb_close_string_substream(stream, &substream);
@@ -1036,8 +1048,22 @@ bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, vo
return false;
/* Check length, noting the null terminator */
- if (size + 1 > field->data_size)
- PB_RETURN_ERROR(stream, "string overflow");
+ if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
+ {
+#ifndef PB_ENABLE_MALLOC
+ PB_RETURN_ERROR(stream, "no malloc support");
+#else
+ *(void**)dest = realloc(*(void**)dest, size + 1);
+ if (*(void**)dest == NULL)
+ PB_RETURN_ERROR(stream, "out of memory");
+ dest = *(void**)dest;
+#endif
+ }
+ else
+ {
+ if (size + 1 > field->data_size)
+ PB_RETURN_ERROR(stream, "string overflow");
+ }
status = pb_read(stream, (uint8_t*)dest, size);
*((uint8_t*)dest + size) = 0;