Expanding the tests to better cover decoding from memory buffer.
[apps/agl-service-can-low-level.git] / pb_decode.c
1 /* pb_decode.c -- decode a protobuf using minimal resources
2  *
3  * 2011 Petteri Aimonen <jpa@kapsi.fi>
4  */
5
6
7 #ifdef __GNUC__
8 /* Verify that we remember to check all return values for proper error propagation */
9 #define checkreturn __attribute__((warn_unused_result))
10 #else
11 #define checkreturn
12 #endif
13
14 #include "pb.h"
15 #include "pb_decode.h"
16 #include <string.h>
17
18 typedef bool (*pb_decoder_t)(pb_istream_t *stream, const pb_field_t *field, void *dest) checkreturn;
19
20 /* --- Function pointers to field decoders ---
21  * Order in the array must match pb_action_t LTYPE numbering.
22  */
23 static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = {
24     &pb_dec_varint,
25     &pb_dec_svarint,
26     &pb_dec_fixed32,
27     &pb_dec_fixed64,
28     
29     &pb_dec_bytes,
30     &pb_dec_string,
31     &pb_dec_submessage
32 };
33
34 /**************
35  * pb_istream *
36  **************/
37
38 bool checkreturn pb_read(pb_istream_t *stream, uint8_t *buf, size_t count)
39 {
40     if (stream->bytes_left < count)
41         return false;
42     
43     if (!stream->callback(stream, buf, count))
44         return false;
45     
46     stream->bytes_left -= count;
47     return true;
48 }
49
50 static bool checkreturn buf_read(pb_istream_t *stream, uint8_t *buf, size_t count)
51 {
52     uint8_t *source = (uint8_t*)stream->state;
53     
54     if (buf != NULL)
55         memcpy(buf, source, count);
56     
57     stream->state = source + count;
58     return true;
59 }
60
61 pb_istream_t pb_istream_from_buffer(uint8_t *buf, size_t bufsize)
62 {
63     pb_istream_t stream;
64     stream.callback = &buf_read;
65     stream.state = buf;
66     stream.bytes_left = bufsize;
67     return stream;
68 }
69
70 /********************
71  * Helper functions *
72  ********************/
73
74 static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)
75 {
76     uint64_t temp;
77     bool status = pb_decode_varint(stream, &temp);
78     *dest = temp;
79     return status;
80 }
81
82 bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest)
83 {
84     uint8_t byte;
85     uint8_t bitpos = 0;
86     *dest = 0;
87     
88     while (bitpos < 64 && pb_read(stream, &byte, 1))
89     {
90         *dest |= (uint64_t)(byte & 0x7F) << bitpos;
91         bitpos += 7;
92         
93         if (!(byte & 0x80))
94             return true;
95     }
96     
97     return false;
98 }
99
100 bool checkreturn pb_skip_varint(pb_istream_t *stream)
101 {
102     uint8_t byte;
103     do
104     {
105         if (!pb_read(stream, &byte, 1))
106             return false;
107     } while (byte & 0x80);
108     return true;
109 }
110
111 bool checkreturn pb_skip_string(pb_istream_t *stream)
112 {
113     uint32_t length;
114     if (!pb_decode_varint32(stream, &length))
115         return false;
116     
117     return pb_read(stream, NULL, length);
118 }
119
120 /* Currently the wire type related stuff is kept hidden from
121  * callbacks. They shouldn't need it. It's better for performance
122  * to just assume the correct type and fail safely on corrupt message.
123  */
124
125 static bool checkreturn skip(pb_istream_t *stream, pb_wire_type_t wire_type)
126 {
127     switch (wire_type)
128     {
129         case PB_WT_VARINT: return pb_skip_varint(stream);
130         case PB_WT_64BIT: return pb_read(stream, NULL, 8);
131         case PB_WT_STRING: return pb_skip_string(stream);
132         case PB_WT_32BIT: return pb_read(stream, NULL, 4);
133         default: return false;
134     }
135 }
136
137 /* Read a raw value to buffer, for the purpose of passing it to callback as
138  * a substream. Size is maximum size on call, and actual size on return.
139  */
140 static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, uint8_t *buf, size_t *size)
141 {
142     size_t max_size = *size;
143     switch (wire_type)
144     {
145         case PB_WT_VARINT:
146             *size = 0;
147             do
148             {
149                 (*size)++;
150                 if (*size > max_size) return false;
151                 if (!pb_read(stream, buf, 1)) return false;
152             } while (*buf++ & 0x80);
153             return true;
154             
155         case PB_WT_64BIT:
156             *size = 8;
157             return pb_read(stream, buf, 8);
158         
159         case PB_WT_32BIT:
160             *size = 4;
161             return pb_read(stream, buf, 4);
162         
163         default: return false;
164     }
165 }
166
167 /* Decode string length from stream and return a substream with limited length.
168  * Before disposing the substream, remember to copy the substream->state back
169  * to stream->state.
170  */
171 static bool checkreturn make_string_substream(pb_istream_t *stream, pb_istream_t *substream)
172 {
173     uint32_t size;
174     if (!pb_decode_varint32(stream, &size))
175         return false;
176     
177     *substream = *stream;
178     if (substream->bytes_left < size)
179         return false;
180     
181     substream->bytes_left = size;
182     stream->bytes_left -= size;
183     return true;
184 }
185
186 /* Iterator for pb_field_t list */
187 typedef struct {
188     const pb_field_t *start;
189     const pb_field_t *current;
190     int field_index;
191     void *dest_struct;
192     void *pData;
193     void *pSize;
194 } pb_field_iterator_t;
195
196 static void pb_field_init(pb_field_iterator_t *iter, const pb_field_t *fields, void *dest_struct)
197 {
198     iter->start = iter->current = fields;
199     iter->field_index = 0;
200     iter->pData = (char*)dest_struct + iter->current->data_offset;
201     iter->pSize = (char*)iter->pData + iter->current->size_offset;
202     iter->dest_struct = dest_struct;
203 }
204
205 static bool pb_field_next(pb_field_iterator_t *iter)
206 {
207     bool notwrapped = true;
208     size_t prev_size = iter->current->data_size;
209     
210     if (PB_HTYPE(iter->current->type) == PB_HTYPE_ARRAY)
211         prev_size *= iter->current->array_size;
212     
213     iter->current++;
214     iter->field_index++;
215     if (iter->current->tag == 0)
216     {
217         iter->current = iter->start;
218         iter->field_index = 0;
219         iter->pData = iter->dest_struct;
220         prev_size = 0;
221         notwrapped = false;
222     }
223     
224     iter->pData = (char*)iter->pData + prev_size + iter->current->data_offset;
225     iter->pSize = (char*)iter->pData + iter->current->size_offset;
226     return notwrapped;
227 }
228
229 static bool checkreturn pb_field_find(pb_field_iterator_t *iter, int tag)
230 {
231     int start = iter->field_index;
232     
233     do {
234         if (iter->current->tag == tag)
235             return true;
236         pb_field_next(iter);
237     } while (iter->field_index != start);
238     
239     return false;
240 }
241
242 /*************************
243  * Decode a single field *
244  *************************/
245
246 static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
247 {
248     pb_decoder_t func = PB_DECODERS[PB_LTYPE(iter->current->type)];
249     
250     switch (PB_HTYPE(iter->current->type))
251     {
252         case PB_HTYPE_REQUIRED:
253             return func(stream, iter->current, iter->pData);
254             
255         case PB_HTYPE_OPTIONAL:
256             *(bool*)iter->pSize = true;
257             return func(stream, iter->current, iter->pData);
258     
259         case PB_HTYPE_ARRAY:
260             if (wire_type == PB_WT_STRING
261                 && PB_LTYPE(iter->current->type) <= PB_LTYPE_LAST_PACKABLE)
262             {
263                 /* Packed array */
264                 size_t *size = (size_t*)iter->pSize;
265                 pb_istream_t substream;
266                 if (!make_string_substream(stream, &substream))
267                     return false;
268                 
269                 while (substream.bytes_left && *size < iter->current->array_size)
270                 {
271                     void *pItem = (uint8_t*)iter->pData + iter->current->data_size * (*size);
272                     if (!func(&substream, iter->current, pItem))
273                         return false;
274                     (*size)++;
275                 }
276                 return (substream.bytes_left == 0);
277             }
278             else
279             {
280                 /* Repeated field */
281                 size_t *size = (size_t*)iter->pSize;
282                 void *pItem = (uint8_t*)iter->pData + iter->current->data_size * (*size);
283                 if (*size >= iter->current->array_size)
284                     return false;
285                 
286                 (*size)++;
287                 return func(stream, iter->current, pItem);
288             }
289         
290         case PB_HTYPE_CALLBACK:
291         {
292             pb_callback_t *pCallback = (pb_callback_t*)iter->pData;
293             
294             if (pCallback->funcs.decode == NULL)
295                 return skip(stream, wire_type);
296             
297             if (wire_type == PB_WT_STRING)
298             {
299                 pb_istream_t substream;
300                 
301                 if (!make_string_substream(stream, &substream))
302                     return false;
303                 
304                 while (substream.bytes_left)
305                 {
306                     if (!pCallback->funcs.decode(&substream, iter->current, pCallback->arg))
307                         return false;
308                 }
309                 
310                 stream->state = substream.state;
311                 return true;
312             }
313             else
314             {
315                 /* Copy the single scalar value to stack.
316                  * This is required so that we can limit the stream length,
317                  * which in turn allows to use same callback for packed and
318                  * not-packed fields. */
319                 pb_istream_t substream;
320                 uint8_t buffer[10];
321                 size_t size = sizeof(buffer);
322                 
323                 if (!read_raw_value(stream, wire_type, buffer, &size))
324                     return false;
325                 substream = pb_istream_from_buffer(buffer, size);
326                 
327                 return pCallback->funcs.decode(&substream, iter->current, pCallback->arg);
328             }
329         }
330         
331         default:
332             return false;
333     }
334 }
335
336 /* Initialize message fields to default values, recursively */
337 static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct)
338 {
339     pb_field_iterator_t iter;
340     pb_field_init(&iter, fields, dest_struct);
341     
342     /* Initialize size/has fields and apply default values */
343     do
344     {
345         if (iter.current->tag == 0)
346             continue;
347         
348         /* Initialize the size field for optional/repeated fields to 0. */
349         if (PB_HTYPE(iter.current->type) == PB_HTYPE_OPTIONAL)
350         {
351             *(bool*)iter.pSize = false;
352         }
353         else if (PB_HTYPE(iter.current->type) == PB_HTYPE_ARRAY)
354         {
355             *(size_t*)iter.pSize = 0;
356             continue; /* Array is empty, no need to initialize contents */
357         }
358         
359         /* Initialize field contents to default value */
360         if (PB_HTYPE(iter.current->type) == PB_HTYPE_CALLBACK)
361         {
362             continue; /* Don't overwrite callback */
363         }
364         else if (PB_LTYPE(iter.current->type) == PB_LTYPE_SUBMESSAGE)
365         {
366             pb_message_set_to_defaults(iter.current->ptr, iter.pData);
367         }
368         else if (iter.current->ptr != NULL)
369         {
370             memcpy(iter.pData, iter.current->ptr, iter.current->data_size);
371         }
372         else
373         {
374             memset(iter.pData, 0, iter.current->data_size);
375         }
376     } while (pb_field_next(&iter));
377 }
378
379 /*********************
380  * Decode all fields *
381  *********************/
382
383 bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
384 {
385     uint32_t fields_seen = 0; /* Used to check for required fields */
386     pb_field_iterator_t iter;
387     int i;
388     
389     pb_message_set_to_defaults(fields, dest_struct);
390     
391     pb_field_init(&iter, fields, dest_struct);
392     
393     while (stream->bytes_left)
394     {
395         uint32_t temp;
396         int tag;
397         pb_wire_type_t wire_type;
398         if (!pb_decode_varint32(stream, &temp))
399         {
400             if (stream->bytes_left == 0)
401                 break; /* It was EOF */
402             else
403                 return false; /* It was error */
404         }
405         
406         if (temp == 0)
407             break; /* Special feature: allow 0-terminated messages. */
408         
409         tag = temp >> 3;
410         wire_type = (pb_wire_type_t)(temp & 7);
411         
412         if (!pb_field_find(&iter, tag))
413         {
414             /* No match found, skip data */
415             if (!skip(stream, wire_type))
416                 return false;
417             continue;
418         }
419         
420         fields_seen |= 1 << (iter.field_index & 31);
421             
422         if (!decode_field(stream, wire_type, &iter))
423             return false;
424     }
425     
426     /* Check that all required fields (mod 31) were present. */
427     for (i = 0; fields[i].tag != 0; i++)
428     {
429         if (PB_HTYPE(fields[i].type) == PB_HTYPE_REQUIRED &&
430             !(fields_seen & (1 << (i & 31))))
431         {
432             return false;
433         }
434     }
435     
436     return true;
437 }
438
439 /* Field decoders */
440
441 /* Copy destsize bytes from src so that values are casted properly.
442  * On little endian machine, copy first n bytes of src
443  * On big endian machine, copy last n bytes of src
444  * srcsize must always be larger than destsize
445  */
446 static void endian_copy(void *dest, void *src, size_t destsize, size_t srcsize)
447 {
448 #ifdef __BIG_ENDIAN__
449     memcpy(dest, (char*)src + (srcsize - destsize), destsize);
450 #else
451     memcpy(dest, src, destsize);
452 #endif
453 }
454
455 bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest)
456 {
457     uint64_t temp;
458     bool status = pb_decode_varint(stream, &temp);
459     endian_copy(dest, &temp, field->data_size, sizeof(temp));
460     return status;
461 }
462
463 bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest)
464 {
465     uint64_t temp;
466     bool status = pb_decode_varint(stream, &temp);
467     temp = (temp >> 1) ^ -(int64_t)(temp & 1);
468     endian_copy(dest, &temp, field->data_size, sizeof(temp));
469     return status;
470 }
471
472 bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest)
473 {
474 #ifdef __BIG_ENDIAN__
475     uint8_t bytes[4] = {0};
476     bool status = pb_read(stream, bytes, 4);
477     if (status) {
478       uint8_t bebytes[4] = {bytes[3], bytes[2], bytes[1], bytes[0]};
479       memcpy(dest, bebytes, 4);
480     }
481     return status;
482 #else
483     return pb_read(stream, (uint8_t*)dest, 4);
484 #endif
485 }
486
487 bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest)
488 {
489 #ifdef __BIG_ENDIAN__
490     uint8_t bytes[8] = {0};
491     bool status = pb_read(stream, bytes, 8);
492     if (status) {
493       uint8_t bebytes[8] = {bytes[7], bytes[6], bytes[5], bytes[4], 
494                             bytes[3], bytes[2], bytes[1], bytes[0]};
495       memcpy(dest, bebytes, 8);
496     }
497     return status;
498 #else
499     return pb_read(stream, (uint8_t*)dest, 8);
500 #endif
501 }
502
503 bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest)
504 {
505     pb_bytes_array_t *x = (pb_bytes_array_t*)dest;
506     
507     uint32_t temp;
508     if (!pb_decode_varint32(stream, &temp))
509         return false;
510     x->size = temp;
511     
512     if (x->size > field->data_size)
513         return false;
514     
515     return pb_read(stream, x->bytes, x->size);
516 }
517
518 bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest)
519 {
520     uint32_t size;
521     bool status;
522     if (!pb_decode_varint32(stream, &size))
523         return false;
524     
525     if (size > field->data_size - 1)
526         return false;
527     
528     status = pb_read(stream, (uint8_t*)dest, size);
529     *((uint8_t*)dest + size) = 0;
530     return status;
531 }
532
533 bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest)
534 {
535     bool status;
536     pb_istream_t substream;
537     
538     if (!make_string_substream(stream, &substream))
539         return false;
540     
541     if (field->ptr == NULL)
542         return false;
543     
544     status = pb_decode(&substream, (pb_field_t*)field->ptr, dest);
545     stream->state = substream.state;
546     return status;
547 }