Add testcase for issue #229
[apps/agl-service-can-low-level.git] / pb_decode.c
index 1699091..b2a3a31 100644 (file)
@@ -65,7 +65,8 @@ static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = {
     &pb_dec_bytes,
     &pb_dec_string,
     &pb_dec_submessage,
-    NULL /* extensions */
+    NULL, /* extensions */
+    &pb_dec_bytes /* PB_LTYPE_FIXED_LENGTH_BYTES */
 };
 
 /*******************************
@@ -74,13 +75,14 @@ static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = {
 
 static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count)
 {
+    size_t i;
     const pb_byte_t *source = (const pb_byte_t*)stream->state;
     stream->state = (pb_byte_t*)stream->state + count;
     
     if (buf != NULL)
     {
-        while (count--)
-            *buf++ = *source++;
+        for (i = 0; i < count; i++)
+            buf[i] = source[i];
     }
     
     return true;
@@ -359,7 +361,8 @@ static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t
             return func(stream, iter->pos, iter->pData);
             
         case PB_HTYPE_OPTIONAL:
-            *(bool*)iter->pSize = true;
+            if (iter->pSize != iter->pData)
+                *(bool*)iter->pSize = true;
             return func(stream, iter->pos, iter->pData);
     
         case PB_HTYPE_REPEATED:
@@ -1035,6 +1038,12 @@ static void pb_release_single_field(const pb_field_iter_t *iter)
         if (PB_HTYPE(type) == PB_HTYPE_REPEATED)
         {
             count = *(pb_size_t*)iter->pSize;
+
+            if (PB_ATYPE(type) == PB_ATYPE_STATIC && count > iter->pos->array_size)
+            {
+                /* Protect against corrupted _count fields */
+                count = iter->pos->array_size;
+            }
         }
         
         if (pItem)
@@ -1266,6 +1275,12 @@ static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *fie
     }
     else
     {
+        if (PB_LTYPE(field->type) == PB_LTYPE_FIXED_LENGTH_BYTES) {
+            if (size != field->data_size)
+                PB_RETURN_ERROR(stream, "incorrect inline bytes size");
+            return pb_read(stream, (pb_byte_t*)dest, field->data_size);
+        }
+
         if (alloc_size > field->data_size)
             PB_RETURN_ERROR(stream, "bytes overflow");
         bdest = (pb_bytes_array_t*)dest;