Fixed issue 1 reported by Erik Rosen:
[apps/agl-service-can-low-level.git] / pb_decode.c
index 453b1cc..1e2fea0 100644 (file)
@@ -122,7 +122,7 @@ bool checkreturn pb_skip_string(pb_istream_t *stream)
  * to just assume the correct type and fail safely on corrupt message.
  */
 
-static bool checkreturn skip(pb_istream_t *stream, int wire_type)
+static bool checkreturn skip(pb_istream_t *stream, pb_wire_type_t wire_type)
 {
     switch (wire_type)
     {
@@ -197,7 +197,7 @@ static void pb_field_init(pb_field_iterator_t *iter, const pb_field_t *fields, v
 {
     iter->start = iter->current = fields;
     iter->field_index = 0;
-    iter->pData = dest_struct + iter->current->data_offset;
+    iter->pData = (char*)dest_struct + iter->current->data_offset;
     iter->pSize = (char*)iter->pData + iter->current->size_offset;
     iter->dest_struct = dest_struct;
 }
@@ -243,7 +243,7 @@ static bool checkreturn pb_field_find(pb_field_iterator_t *iter, int tag)
  * Decode a single field *
  *************************/
 
-static bool checkreturn decode_field(pb_istream_t *stream, int wire_type, pb_field_iterator_t *iter)
+static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
 {
     pb_decoder_t func = PB_DECODERS[PB_LTYPE(iter->current->type)];
     
@@ -393,7 +393,8 @@ bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void
     while (stream->bytes_left)
     {
         uint32_t temp;
-        int tag, wire_type;
+        int tag;
+        pb_wire_type_t wire_type;
         if (!pb_decode_varint32(stream, &temp))
         {
             if (stream->bytes_left == 0)
@@ -406,7 +407,7 @@ bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void
             break; /* Special feature: allow 0-terminated messages. */
         
         tag = temp >> 3;
-        wire_type = temp & 7;
+        wire_type = (pb_wire_type_t)(temp & 7);
         
         if (!pb_field_find(&iter, tag))
         {
@@ -473,8 +474,10 @@ bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, v
 #ifdef __BIG_ENDIAN__
     uint8_t bytes[4] = {0};
     bool status = pb_read(stream, bytes, 4);
-    uint8_t bebytes[4] = {bytes[3], bytes[2], bytes[1], bytes[0]};
-    memcpy(dest, bebytes, 4);
+    if (status) {
+      uint8_t bebytes[4] = {bytes[3], bytes[2], bytes[1], bytes[0]};
+      memcpy(dest, bebytes, 4);
+    }
     return status;
 #else
     return pb_read(stream, (uint8_t*)dest, 4);
@@ -486,9 +489,11 @@ bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, v
 #ifdef __BIG_ENDIAN__
     uint8_t bytes[8] = {0};
     bool status = pb_read(stream, bytes, 8);
-    uint8_t bebytes[8] = {bytes[7], bytes[6], bytes[5], bytes[4], 
-                          bytes[3], bytes[2], bytes[1], bytes[0]};
-    memcpy(dest, bebytes, 8);
+    if (status) {
+      uint8_t bebytes[8] = {bytes[7], bytes[6], bytes[5], bytes[4], 
+                            bytes[3], bytes[2], bytes[1], bytes[0]};
+      memcpy(dest, bebytes, 8);
+    }
     return status;
 #else
     return pb_read(stream, (uint8_t*)dest, 8);
@@ -504,7 +509,8 @@ bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, voi
         return false;
     x->size = temp;
     
-    if (x->size > field->data_size)
+    /* Check length, noting the space taken by the size_t header. */
+    if (x->size > field->data_size - offsetof(pb_bytes_array_t, bytes))
         return false;
     
     return pb_read(stream, x->bytes, x->size);
@@ -517,6 +523,7 @@ bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, vo
     if (!pb_decode_varint32(stream, &size))
         return false;
     
+    /* Check length, noting the null terminator */
     if (size > field->data_size - 1)
         return false;