1 /*
2  * Copyright (c) 2008-2015, Dave Benson and the protobuf-c authors.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  *     * Redistributions in binary form must reproduce the above
13  * copyright notice, this list of conditions and the following disclaimer
14  * in the documentation and/or other materials provided with the
15  * distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /*! \file
31  * Support library for `protoc-c` generated code.
32  *
33  * This file implements the public API used by the code generated
34  * by `protoc-c`.
35  *
36  * \authors Dave Benson and the protobuf-c authors
37  *
38  * \copyright 2008-2014. Licensed under the terms of the [BSD-2-Clause] license.
39  */
40 
41 /**
42  * \todo 64-BIT OPTIMIZATION: certain implementations use 32-bit math
43  * even on 64-bit platforms (uint64_size, uint64_pack, parse_uint64).
44  *
45  * \todo Use size_t consistently.
46  */
47 
48 #include <stdlib.h>	/* for malloc, free */
49 #include <string.h>	/* for strcmp, strlen, memcpy, memmove, memset */
50 
51 #include "protobuf-c.h"
52 
53 #define TRUE				1
54 #define FALSE				0
55 
56 #define PROTOBUF_C__ASSERT_NOT_REACHED() assert(0)
57 
58 /* Workaround for Microsoft compilers. */
59 #ifdef _MSC_VER
60 # define inline __inline
61 #endif
62 
63 /**
64  * \defgroup internal Internal functions and macros
65  *
66  * These are not exported by the library but are useful to developers working
67  * on `libprotobuf-c` itself.
68  */
69 
70 /**
71  * \defgroup macros Utility macros for manipulating structures
72  *
73  * Macros and constants used to manipulate the base "classes" generated by
74  * `protobuf-c`. They also define limits and check correctness.
75  *
76  * \ingroup internal
77  * @{
78  */
79 
80 /** The maximum length of a 64-bit integer in varint encoding. */
81 #define MAX_UINT64_ENCODED_SIZE		10
82 
83 #ifndef PROTOBUF_C_UNPACK_ERROR
84 # define PROTOBUF_C_UNPACK_ERROR(...)
85 #endif
86 
87 #if !defined(_WIN32) || !defined(PROTOBUF_C_USE_SHARED_LIB)
88 const char protobuf_c_empty_string[] = "";
89 #endif
90 
91 /**
92  * Internal `ProtobufCMessage` manipulation macro.
93  *
94  * Base macro for manipulating a `ProtobufCMessage`. Used by STRUCT_MEMBER() and
95  * STRUCT_MEMBER_PTR().
96  */
97 #define STRUCT_MEMBER_P(struct_p, struct_offset) \
98     ((void *) ((uint8_t *) (struct_p) + (struct_offset)))
99 
100 /**
101  * Return field in a `ProtobufCMessage` based on offset.
102  *
103  * Take a pointer to a `ProtobufCMessage` and find the field at the offset.
104  * Cast it to the passed type.
105  */
106 #define STRUCT_MEMBER(member_type, struct_p, struct_offset) \
107     (*(member_type *) STRUCT_MEMBER_P((struct_p), (struct_offset)))
108 
109 /**
110  * Return field in a `ProtobufCMessage` based on offset.
111  *
112  * Take a pointer to a `ProtobufCMessage` and find the field at the offset. Cast
113  * it to a pointer to the passed type.
114  */
115 #define STRUCT_MEMBER_PTR(member_type, struct_p, struct_offset) \
116     ((member_type *) STRUCT_MEMBER_P((struct_p), (struct_offset)))
117 
118 /* Assertions for magic numbers. */
119 
120 #define ASSERT_IS_ENUM_DESCRIPTOR(desc) \
121 	assert((desc)->magic == PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC)
122 
123 #define ASSERT_IS_MESSAGE_DESCRIPTOR(desc) \
124 	assert((desc)->magic == PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC)
125 
126 #define ASSERT_IS_MESSAGE(message) \
127 	ASSERT_IS_MESSAGE_DESCRIPTOR((message)->descriptor)
128 
129 #define ASSERT_IS_SERVICE_DESCRIPTOR(desc) \
130 	assert((desc)->magic == PROTOBUF_C__SERVICE_DESCRIPTOR_MAGIC)
131 
132 /**@}*/
133 
134 /* --- version --- */
135 
136 const char *
protobuf_c_version(void)137 protobuf_c_version(void)
138 {
139 	return PROTOBUF_C_VERSION;
140 }
141 
142 uint32_t
protobuf_c_version_number(void)143 protobuf_c_version_number(void)
144 {
145 	return PROTOBUF_C_VERSION_NUMBER;
146 }
147 
148 /* --- allocator --- */
149 
150 static void *
system_alloc(void * allocator_data,size_t size)151 system_alloc(void *allocator_data, size_t size)
152 {
153 	(void)allocator_data;
154 	return malloc(size);
155 }
156 
157 static void
system_free(void * allocator_data,void * data)158 system_free(void *allocator_data, void *data)
159 {
160 	(void)allocator_data;
161 	free(data);
162 }
163 
164 static inline void *
do_alloc(ProtobufCAllocator * allocator,size_t size)165 do_alloc(ProtobufCAllocator *allocator, size_t size)
166 {
167 	return allocator->alloc(allocator->allocator_data, size);
168 }
169 
170 static inline void
do_free(ProtobufCAllocator * allocator,void * data)171 do_free(ProtobufCAllocator *allocator, void *data)
172 {
173 	if (data != NULL)
174 		allocator->free(allocator->allocator_data, data);
175 }
176 
177 /*
178  * This allocator uses the system's malloc() and free(). It is the default
179  * allocator used if NULL is passed as the ProtobufCAllocator to an exported
180  * function.
181  */
182 static ProtobufCAllocator protobuf_c__allocator = {
183 	.alloc = &system_alloc,
184 	.free = &system_free,
185 	.allocator_data = NULL,
186 };
187 
188 /* === buffer-simple === */
189 
190 void
protobuf_c_buffer_simple_append(ProtobufCBuffer * buffer,size_t len,const uint8_t * data)191 protobuf_c_buffer_simple_append(ProtobufCBuffer *buffer,
192 				size_t len, const uint8_t *data)
193 {
194 	ProtobufCBufferSimple *simp = (ProtobufCBufferSimple *) buffer;
195 	size_t new_len = simp->len + len;
196 
197 	if (new_len > simp->alloced) {
198 		ProtobufCAllocator *allocator = simp->allocator;
199 		size_t new_alloced = simp->alloced * 2;
200 		uint8_t *new_data;
201 
202 		if (allocator == NULL)
203 			allocator = &protobuf_c__allocator;
204 		while (new_alloced < new_len)
205 			new_alloced += new_alloced;
206 		new_data = do_alloc(allocator, new_alloced);
207 		if (!new_data)
208 			return;
209 		memcpy(new_data, simp->data, simp->len);
210 		if (simp->must_free_data)
211 			do_free(allocator, simp->data);
212 		else
213 			simp->must_free_data = TRUE;
214 		simp->data = new_data;
215 		simp->alloced = new_alloced;
216 	}
217 	memcpy(simp->data + simp->len, data, len);
218 	simp->len = new_len;
219 }
220 
221 /**
222  * \defgroup packedsz protobuf_c_message_get_packed_size() implementation
223  *
224  * Routines mainly used by protobuf_c_message_get_packed_size().
225  *
226  * \ingroup internal
227  * @{
228  */
229 
230 /**
231  * Return the number of bytes required to store the tag for the field. Includes
232  * 3 bits for the wire-type, and a single bit that denotes the end-of-tag.
233  *
234  * \param number
235  *      Field tag to encode.
236  * \return
237  *      Number of bytes required.
238  */
239 static inline size_t
get_tag_size(uint32_t number)240 get_tag_size(uint32_t number)
241 {
242 	if (number < (1UL << 4)) {
243 		return 1;
244 	} else if (number < (1UL << 11)) {
245 		return 2;
246 	} else if (number < (1UL << 18)) {
247 		return 3;
248 	} else if (number < (1UL << 25)) {
249 		return 4;
250 	} else {
251 		return 5;
252 	}
253 }
254 
255 /**
256  * Return the number of bytes required to store a variable-length unsigned
257  * 32-bit integer in base-128 varint encoding.
258  *
259  * \param v
260  *      Value to encode.
261  * \return
262  *      Number of bytes required.
263  */
264 static inline size_t
uint32_size(uint32_t v)265 uint32_size(uint32_t v)
266 {
267 	if (v < (1UL << 7)) {
268 		return 1;
269 	} else if (v < (1UL << 14)) {
270 		return 2;
271 	} else if (v < (1UL << 21)) {
272 		return 3;
273 	} else if (v < (1UL << 28)) {
274 		return 4;
275 	} else {
276 		return 5;
277 	}
278 }
279 
280 /**
281  * Return the number of bytes required to store a variable-length signed 32-bit
282  * integer in base-128 varint encoding.
283  *
284  * \param v
285  *      Value to encode.
286  * \return
287  *      Number of bytes required.
288  */
289 static inline size_t
int32_size(int32_t v)290 int32_size(int32_t v)
291 {
292 	if (v < 0) {
293 		return 10;
294 	} else if (v < (1L << 7)) {
295 		return 1;
296 	} else if (v < (1L << 14)) {
297 		return 2;
298 	} else if (v < (1L << 21)) {
299 		return 3;
300 	} else if (v < (1L << 28)) {
301 		return 4;
302 	} else {
303 		return 5;
304 	}
305 }
306 
307 /**
308  * Return the ZigZag-encoded 32-bit unsigned integer form of a 32-bit signed
309  * integer.
310  *
311  * \param v
312  *      Value to encode.
313  * \return
314  *      ZigZag encoded integer.
315  */
316 static inline uint32_t
zigzag32(int32_t v)317 zigzag32(int32_t v)
318 {
319 	// Note:  the right-shift must be arithmetic
320 	// Note:  left shift must be unsigned because of overflow
321 	return ((uint32_t)(v) << 1) ^ (uint32_t)(v >> 31);
322 }
323 
324 /**
325  * Return the number of bytes required to store a signed 32-bit integer,
326  * converted to an unsigned 32-bit integer with ZigZag encoding, using base-128
327  * varint encoding.
328  *
329  * \param v
330  *      Value to encode.
331  * \return
332  *      Number of bytes required.
333  */
334 static inline size_t
sint32_size(int32_t v)335 sint32_size(int32_t v)
336 {
337 	return uint32_size(zigzag32(v));
338 }
339 
340 /**
341  * Return the number of bytes required to store a 64-bit unsigned integer in
342  * base-128 varint encoding.
343  *
344  * \param v
345  *      Value to encode.
346  * \return
347  *      Number of bytes required.
348  */
349 static inline size_t
uint64_size(uint64_t v)350 uint64_size(uint64_t v)
351 {
352 	uint32_t upper_v = (uint32_t) (v >> 32);
353 
354 	if (upper_v == 0) {
355 		return uint32_size((uint32_t) v);
356 	} else if (upper_v < (1UL << 3)) {
357 		return 5;
358 	} else if (upper_v < (1UL << 10)) {
359 		return 6;
360 	} else if (upper_v < (1UL << 17)) {
361 		return 7;
362 	} else if (upper_v < (1UL << 24)) {
363 		return 8;
364 	} else if (upper_v < (1UL << 31)) {
365 		return 9;
366 	} else {
367 		return 10;
368 	}
369 }
370 
371 /**
372  * Return the ZigZag-encoded 64-bit unsigned integer form of a 64-bit signed
373  * integer.
374  *
375  * \param v
376  *      Value to encode.
377  * \return
378  *      ZigZag encoded integer.
379  */
380 static inline uint64_t
zigzag64(int64_t v)381 zigzag64(int64_t v)
382 {
383 	// Note:  the right-shift must be arithmetic
384 	// Note:  left shift must be unsigned because of overflow
385 	return ((uint64_t)(v) << 1) ^ (uint64_t)(v >> 63);
386 }
387 
388 /**
389  * Return the number of bytes required to store a signed 64-bit integer,
390  * converted to an unsigned 64-bit integer with ZigZag encoding, using base-128
391  * varint encoding.
392  *
393  * \param v
394  *      Value to encode.
395  * \return
396  *      Number of bytes required.
397  */
398 static inline size_t
sint64_size(int64_t v)399 sint64_size(int64_t v)
400 {
401 	return uint64_size(zigzag64(v));
402 }
403 
404 /**
405  * Calculate the serialized size of a single required message field, including
406  * the space needed by the preceding tag.
407  *
408  * \param field
409  *      Field descriptor for member.
410  * \param member
411  *      Field to encode.
412  * \return
413  *      Number of bytes required.
414  */
415 static size_t
required_field_get_packed_size(const ProtobufCFieldDescriptor * field,const void * member)416 required_field_get_packed_size(const ProtobufCFieldDescriptor *field,
417 			       const void *member)
418 {
419 	size_t rv = get_tag_size(field->id);
420 
421 	switch (field->type) {
422 	case PROTOBUF_C_TYPE_SINT32:
423 		return rv + sint32_size(*(const int32_t *) member);
424 	case PROTOBUF_C_TYPE_ENUM:
425 	case PROTOBUF_C_TYPE_INT32:
426 		return rv + int32_size(*(const int32_t *) member);
427 	case PROTOBUF_C_TYPE_UINT32:
428 		return rv + uint32_size(*(const uint32_t *) member);
429 	case PROTOBUF_C_TYPE_SINT64:
430 		return rv + sint64_size(*(const int64_t *) member);
431 	case PROTOBUF_C_TYPE_INT64:
432 	case PROTOBUF_C_TYPE_UINT64:
433 		return rv + uint64_size(*(const uint64_t *) member);
434 	case PROTOBUF_C_TYPE_SFIXED32:
435 	case PROTOBUF_C_TYPE_FIXED32:
436 		return rv + 4;
437 	case PROTOBUF_C_TYPE_SFIXED64:
438 	case PROTOBUF_C_TYPE_FIXED64:
439 		return rv + 8;
440 	case PROTOBUF_C_TYPE_BOOL:
441 		return rv + 1;
442 	case PROTOBUF_C_TYPE_FLOAT:
443 		return rv + 4;
444 	case PROTOBUF_C_TYPE_DOUBLE:
445 		return rv + 8;
446 	case PROTOBUF_C_TYPE_STRING: {
447 		const char *str = *(char * const *) member;
448 		size_t len = str ? strlen(str) : 0;
449 		return rv + uint32_size(len) + len;
450 	}
451 	case PROTOBUF_C_TYPE_BYTES: {
452 		size_t len = ((const ProtobufCBinaryData *) member)->len;
453 		return rv + uint32_size(len) + len;
454 	}
455 	case PROTOBUF_C_TYPE_MESSAGE: {
456 		const ProtobufCMessage *msg = *(ProtobufCMessage * const *) member;
457 		size_t subrv = msg ? protobuf_c_message_get_packed_size(msg) : 0;
458 		return rv + uint32_size(subrv) + subrv;
459 	}
460 	}
461 	PROTOBUF_C__ASSERT_NOT_REACHED();
462 	return 0;
463 }
464 
465 /**
466  * Calculate the serialized size of a single oneof message field, including
467  * the space needed by the preceding tag. Returns 0 if the oneof field isn't
468  * selected or is not set.
469  *
470  * \param field
471  *      Field descriptor for member.
472  * \param oneof_case
473  *      Enum value that selects the field in the oneof.
474  * \param member
475  *      Field to encode.
476  * \return
477  *      Number of bytes required.
478  */
479 static size_t
oneof_field_get_packed_size(const ProtobufCFieldDescriptor * field,uint32_t oneof_case,const void * member)480 oneof_field_get_packed_size(const ProtobufCFieldDescriptor *field,
481 			    uint32_t oneof_case,
482 			    const void *member)
483 {
484 	if (oneof_case != field->id) {
485 		return 0;
486 	}
487 	if (field->type == PROTOBUF_C_TYPE_MESSAGE ||
488 	    field->type == PROTOBUF_C_TYPE_STRING)
489 	{
490 		const void *ptr = *(const void * const *) member;
491 		if (ptr == NULL || ptr == field->default_value)
492 			return 0;
493 	}
494 	return required_field_get_packed_size(field, member);
495 }
496 
497 /**
498  * Calculate the serialized size of a single optional message field, including
499  * the space needed by the preceding tag. Returns 0 if the optional field isn't
500  * set.
501  *
502  * \param field
503  *      Field descriptor for member.
504  * \param has
505  *      True if the field exists, false if not.
506  * \param member
507  *      Field to encode.
508  * \return
509  *      Number of bytes required.
510  */
511 static size_t
optional_field_get_packed_size(const ProtobufCFieldDescriptor * field,const protobuf_c_boolean has,const void * member)512 optional_field_get_packed_size(const ProtobufCFieldDescriptor *field,
513 			       const protobuf_c_boolean has,
514 			       const void *member)
515 {
516 	if (field->type == PROTOBUF_C_TYPE_MESSAGE ||
517 	    field->type == PROTOBUF_C_TYPE_STRING)
518 	{
519 		const void *ptr = *(const void * const *) member;
520 		if (ptr == NULL || ptr == field->default_value)
521 			return 0;
522 	} else {
523 		if (!has)
524 			return 0;
525 	}
526 	return required_field_get_packed_size(field, member);
527 }
528 
529 static protobuf_c_boolean
field_is_zeroish(const ProtobufCFieldDescriptor * field,const void * member)530 field_is_zeroish(const ProtobufCFieldDescriptor *field,
531 		 const void *member)
532 {
533 	protobuf_c_boolean ret = FALSE;
534 
535 	switch (field->type) {
536 	case PROTOBUF_C_TYPE_BOOL:
537 		ret = (0 == *(const protobuf_c_boolean *) member);
538 		break;
539 	case PROTOBUF_C_TYPE_ENUM:
540 	case PROTOBUF_C_TYPE_SINT32:
541 	case PROTOBUF_C_TYPE_INT32:
542 	case PROTOBUF_C_TYPE_UINT32:
543 	case PROTOBUF_C_TYPE_SFIXED32:
544 	case PROTOBUF_C_TYPE_FIXED32:
545 		ret = (0 == *(const uint32_t *) member);
546 		break;
547 	case PROTOBUF_C_TYPE_SINT64:
548 	case PROTOBUF_C_TYPE_INT64:
549 	case PROTOBUF_C_TYPE_UINT64:
550 	case PROTOBUF_C_TYPE_SFIXED64:
551 	case PROTOBUF_C_TYPE_FIXED64:
552 		ret = (0 == *(const uint64_t *) member);
553 		break;
554 	case PROTOBUF_C_TYPE_FLOAT:
555 		ret = (0 == *(const float *) member);
556 		break;
557 	case PROTOBUF_C_TYPE_DOUBLE:
558 		ret = (0 == *(const double *) member);
559 		break;
560 	case PROTOBUF_C_TYPE_STRING:
561 		ret = (NULL == *(const char * const *) member) ||
562 		      ('\0' == **(const char * const *) member);
563 		break;
564 	case PROTOBUF_C_TYPE_BYTES:
565 	case PROTOBUF_C_TYPE_MESSAGE:
566 		ret = (NULL == *(const void * const *) member);
567 		break;
568 	default:
569 		ret = TRUE;
570 		break;
571 	}
572 
573 	return ret;
574 }
575 
576 /**
577  * Calculate the serialized size of a single unlabeled message field, including
578  * the space needed by the preceding tag. Returns 0 if the field isn't set or
579  * if it is set to a "zeroish" value (null pointer or 0 for numerical values).
580  * Unlabeled fields are supported only in proto3.
581  *
582  * \param field
583  *      Field descriptor for member.
584  * \param member
585  *      Field to encode.
586  * \return
587  *      Number of bytes required.
588  */
589 static size_t
unlabeled_field_get_packed_size(const ProtobufCFieldDescriptor * field,const void * member)590 unlabeled_field_get_packed_size(const ProtobufCFieldDescriptor *field,
591 				const void *member)
592 {
593 	if (field_is_zeroish(field, member))
594 		return 0;
595 	return required_field_get_packed_size(field, member);
596 }
597 
598 /**
599  * Calculate the serialized size of repeated message fields, which may consist
600  * of any number of values (including 0). Includes the space needed by the
601  * preceding tags (as needed).
602  *
603  * \param field
604  *      Field descriptor for member.
605  * \param count
606  *      Number of repeated field members.
607  * \param member
608  *      Field to encode.
609  * \return
610  *      Number of bytes required.
611  */
612 static size_t
repeated_field_get_packed_size(const ProtobufCFieldDescriptor * field,size_t count,const void * member)613 repeated_field_get_packed_size(const ProtobufCFieldDescriptor *field,
614 			       size_t count, const void *member)
615 {
616 	size_t header_size;
617 	size_t rv = 0;
618 	unsigned i;
619 	void *array = *(void * const *) member;
620 
621 	if (count == 0)
622 		return 0;
623 	header_size = get_tag_size(field->id);
624 	if (0 == (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED))
625 		header_size *= count;
626 
627 	switch (field->type) {
628 	case PROTOBUF_C_TYPE_SINT32:
629 		for (i = 0; i < count; i++)
630 			rv += sint32_size(((int32_t *) array)[i]);
631 		break;
632 	case PROTOBUF_C_TYPE_ENUM:
633 	case PROTOBUF_C_TYPE_INT32:
634 		for (i = 0; i < count; i++)
635 			rv += int32_size(((int32_t *) array)[i]);
636 		break;
637 	case PROTOBUF_C_TYPE_UINT32:
638 		for (i = 0; i < count; i++)
639 			rv += uint32_size(((uint32_t *) array)[i]);
640 		break;
641 	case PROTOBUF_C_TYPE_SINT64:
642 		for (i = 0; i < count; i++)
643 			rv += sint64_size(((int64_t *) array)[i]);
644 		break;
645 	case PROTOBUF_C_TYPE_INT64:
646 	case PROTOBUF_C_TYPE_UINT64:
647 		for (i = 0; i < count; i++)
648 			rv += uint64_size(((uint64_t *) array)[i]);
649 		break;
650 	case PROTOBUF_C_TYPE_SFIXED32:
651 	case PROTOBUF_C_TYPE_FIXED32:
652 	case PROTOBUF_C_TYPE_FLOAT:
653 		rv += 4 * count;
654 		break;
655 	case PROTOBUF_C_TYPE_SFIXED64:
656 	case PROTOBUF_C_TYPE_FIXED64:
657 	case PROTOBUF_C_TYPE_DOUBLE:
658 		rv += 8 * count;
659 		break;
660 	case PROTOBUF_C_TYPE_BOOL:
661 		rv += count;
662 		break;
663 	case PROTOBUF_C_TYPE_STRING:
664 		for (i = 0; i < count; i++) {
665 			size_t len = strlen(((char **) array)[i]);
666 			rv += uint32_size(len) + len;
667 		}
668 		break;
669 	case PROTOBUF_C_TYPE_BYTES:
670 		for (i = 0; i < count; i++) {
671 			size_t len = ((ProtobufCBinaryData *) array)[i].len;
672 			rv += uint32_size(len) + len;
673 		}
674 		break;
675 	case PROTOBUF_C_TYPE_MESSAGE:
676 		for (i = 0; i < count; i++) {
677 			size_t len = protobuf_c_message_get_packed_size(
678 				((ProtobufCMessage **) array)[i]);
679 			rv += uint32_size(len) + len;
680 		}
681 		break;
682 	}
683 
684 	if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED))
685 		header_size += uint32_size(rv);
686 	return header_size + rv;
687 }
688 
689 /**
690  * Calculate the serialized size of an unknown field, i.e. one that is passed
691  * through mostly uninterpreted. This is required for forward compatibility if
692  * new fields are added to the message descriptor.
693  *
694  * \param field
695  *      Unknown field type.
696  * \return
697  *      Number of bytes required.
698  */
699 static inline size_t
unknown_field_get_packed_size(const ProtobufCMessageUnknownField * field)700 unknown_field_get_packed_size(const ProtobufCMessageUnknownField *field)
701 {
702 	return get_tag_size(field->tag) + field->len;
703 }
704 
705 /**@}*/
706 
707 /*
708  * Calculate the serialized size of the message.
709  */
protobuf_c_message_get_packed_size(const ProtobufCMessage * message)710 size_t protobuf_c_message_get_packed_size(const ProtobufCMessage *message)
711 {
712 	unsigned i;
713 	size_t rv = 0;
714 
715 	ASSERT_IS_MESSAGE(message);
716 	for (i = 0; i < message->descriptor->n_fields; i++) {
717 		const ProtobufCFieldDescriptor *field =
718 			message->descriptor->fields + i;
719 		const void *member =
720 			((const char *) message) + field->offset;
721 		const void *qmember =
722 			((const char *) message) + field->quantifier_offset;
723 
724 		if (field->label == PROTOBUF_C_LABEL_REQUIRED) {
725 			rv += required_field_get_packed_size(field, member);
726 		} else if ((field->label == PROTOBUF_C_LABEL_OPTIONAL ||
727 			    field->label == PROTOBUF_C_LABEL_NONE) &&
728 			   (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF))) {
729 			rv += oneof_field_get_packed_size(
730 				field,
731 				*(const uint32_t *) qmember,
732 				member
733 			);
734 		} else if (field->label == PROTOBUF_C_LABEL_OPTIONAL) {
735 			rv += optional_field_get_packed_size(
736 				field,
737 				*(protobuf_c_boolean *) qmember,
738 				member
739 			);
740 		} else if (field->label == PROTOBUF_C_LABEL_NONE) {
741 			rv += unlabeled_field_get_packed_size(
742 				field,
743 				member
744 			);
745 		} else {
746 			rv += repeated_field_get_packed_size(
747 				field,
748 				*(const size_t *) qmember,
749 				member
750 			);
751 		}
752 	}
753 	for (i = 0; i < message->n_unknown_fields; i++)
754 		rv += unknown_field_get_packed_size(&message->unknown_fields[i]);
755 	return rv;
756 }
757 
758 /**
759  * \defgroup pack protobuf_c_message_pack() implementation
760  *
761  * Routines mainly used by protobuf_c_message_pack().
762  *
763  * \ingroup internal
764  * @{
765  */
766 
767 /**
768  * Pack an unsigned 32-bit integer in base-128 varint encoding and return the
769  * number of bytes written, which must be 5 or less.
770  *
771  * \param value
772  *      Value to encode.
773  * \param[out] out
774  *      Packed value.
775  * \return
776  *      Number of bytes written to `out`.
777  */
778 static inline size_t
uint32_pack(uint32_t value,uint8_t * out)779 uint32_pack(uint32_t value, uint8_t *out)
780 {
781 	unsigned rv = 0;
782 
783 	if (value >= 0x80) {
784 		out[rv++] = value | 0x80;
785 		value >>= 7;
786 		if (value >= 0x80) {
787 			out[rv++] = value | 0x80;
788 			value >>= 7;
789 			if (value >= 0x80) {
790 				out[rv++] = value | 0x80;
791 				value >>= 7;
792 				if (value >= 0x80) {
793 					out[rv++] = value | 0x80;
794 					value >>= 7;
795 				}
796 			}
797 		}
798 	}
799 	/* assert: value<128 */
800 	out[rv++] = value;
801 	return rv;
802 }
803 
804 /**
805  * Pack a signed 32-bit integer and return the number of bytes written.
806  * Negative numbers are encoded as two's complement 64-bit integers.
807  *
808  * \param value
809  *      Value to encode.
810  * \param[out] out
811  *      Packed value.
812  * \return
813  *      Number of bytes written to `out`.
814  */
815 static inline size_t
int32_pack(int32_t value,uint8_t * out)816 int32_pack(int32_t value, uint8_t *out)
817 {
818 	if (value < 0) {
819 		out[0] = value | 0x80;
820 		out[1] = (value >> 7) | 0x80;
821 		out[2] = (value >> 14) | 0x80;
822 		out[3] = (value >> 21) | 0x80;
823 		out[4] = (value >> 28) | 0x80;
824 		out[5] = out[6] = out[7] = out[8] = 0xff;
825 		out[9] = 0x01;
826 		return 10;
827 	} else {
828 		return uint32_pack(value, out);
829 	}
830 }
831 
832 /**
833  * Pack a signed 32-bit integer using ZigZag encoding and return the number of
834  * bytes written.
835  *
836  * \param value
837  *      Value to encode.
838  * \param[out] out
839  *      Packed value.
840  * \return
841  *      Number of bytes written to `out`.
842  */
843 static inline size_t
sint32_pack(int32_t value,uint8_t * out)844 sint32_pack(int32_t value, uint8_t *out)
845 {
846 	return uint32_pack(zigzag32(value), out);
847 }
848 
849 /**
850  * Pack a 64-bit unsigned integer using base-128 varint encoding and return the
851  * number of bytes written.
852  *
853  * \param value
854  *      Value to encode.
855  * \param[out] out
856  *      Packed value.
857  * \return
858  *      Number of bytes written to `out`.
859  */
860 static size_t
uint64_pack(uint64_t value,uint8_t * out)861 uint64_pack(uint64_t value, uint8_t *out)
862 {
863 	uint32_t hi = (uint32_t) (value >> 32);
864 	uint32_t lo = (uint32_t) value;
865 	unsigned rv;
866 
867 	if (hi == 0)
868 		return uint32_pack((uint32_t) lo, out);
869 	out[0] = (lo) | 0x80;
870 	out[1] = (lo >> 7) | 0x80;
871 	out[2] = (lo >> 14) | 0x80;
872 	out[3] = (lo >> 21) | 0x80;
873 	if (hi < 8) {
874 		out[4] = (hi << 4) | (lo >> 28);
875 		return 5;
876 	} else {
877 		out[4] = ((hi & 7) << 4) | (lo >> 28) | 0x80;
878 		hi >>= 3;
879 	}
880 	rv = 5;
881 	while (hi >= 128) {
882 		out[rv++] = hi | 0x80;
883 		hi >>= 7;
884 	}
885 	out[rv++] = hi;
886 	return rv;
887 }
888 
889 /**
890  * Pack a 64-bit signed integer in ZigZag encoding and return the number of
891  * bytes written.
892  *
893  * \param value
894  *      Value to encode.
895  * \param[out] out
896  *      Packed value.
897  * \return
898  *      Number of bytes written to `out`.
899  */
900 static inline size_t
sint64_pack(int64_t value,uint8_t * out)901 sint64_pack(int64_t value, uint8_t *out)
902 {
903 	return uint64_pack(zigzag64(value), out);
904 }
905 
906 /**
907  * Pack a 32-bit quantity in little-endian byte order. Used for protobuf wire
908  * types fixed32, sfixed32, float. Similar to "htole32".
909  *
910  * \param value
911  *      Value to encode.
912  * \param[out] out
913  *      Packed value.
914  * \return
915  *      Number of bytes written to `out`.
916  */
917 static inline size_t
fixed32_pack(uint32_t value,void * out)918 fixed32_pack(uint32_t value, void *out)
919 {
920 #if !defined(WORDS_BIGENDIAN)
921 	memcpy(out, &value, 4);
922 #else
923 	uint8_t *buf = out;
924 
925 	buf[0] = value;
926 	buf[1] = value >> 8;
927 	buf[2] = value >> 16;
928 	buf[3] = value >> 24;
929 #endif
930 	return 4;
931 }
932 
933 /**
934  * Pack a 64-bit quantity in little-endian byte order. Used for protobuf wire
935  * types fixed64, sfixed64, double. Similar to "htole64".
936  *
937  * \todo The big-endian impl is really only good for 32-bit machines, a 64-bit
938  * version would be appreciated, plus a way to decide to use 64-bit math where
939  * convenient.
940  *
941  * \param value
942  *      Value to encode.
943  * \param[out] out
944  *      Packed value.
945  * \return
946  *      Number of bytes written to `out`.
947  */
948 static inline size_t
fixed64_pack(uint64_t value,void * out)949 fixed64_pack(uint64_t value, void *out)
950 {
951 #if !defined(WORDS_BIGENDIAN)
952 	memcpy(out, &value, 8);
953 #else
954 	fixed32_pack(value, out);
955 	fixed32_pack(value >> 32, ((char *) out) + 4);
956 #endif
957 	return 8;
958 }
959 
960 /**
961  * Pack a boolean value as an integer and return the number of bytes written.
962  *
963  * \todo Perhaps on some platforms *out = !!value would be a better impl, b/c
964  * that is idiomatic C++ in some STL implementations.
965  *
966  * \param value
967  *      Value to encode.
968  * \param[out] out
969  *      Packed value.
970  * \return
971  *      Number of bytes written to `out`.
972  */
973 static inline size_t
boolean_pack(protobuf_c_boolean value,uint8_t * out)974 boolean_pack(protobuf_c_boolean value, uint8_t *out)
975 {
976 	*out = value ? TRUE : FALSE;
977 	return 1;
978 }
979 
980 /**
981  * Pack a NUL-terminated C string and return the number of bytes written. The
982  * output includes a length delimiter.
983  *
984  * The NULL pointer is treated as an empty string. This isn't really necessary,
985  * but it allows people to leave required strings blank. (See Issue #13 in the
986  * bug tracker for a little more explanation).
987  *
988  * \param str
989  *      String to encode.
990  * \param[out] out
991  *      Packed value.
992  * \return
993  *      Number of bytes written to `out`.
994  */
995 static inline size_t
string_pack(const char * str,uint8_t * out)996 string_pack(const char *str, uint8_t *out)
997 {
998 	if (str == NULL) {
999 		out[0] = 0;
1000 		return 1;
1001 	} else {
1002 		size_t len = strlen(str);
1003 		size_t rv = uint32_pack(len, out);
1004 		memcpy(out + rv, str, len);
1005 		return rv + len;
1006 	}
1007 }
1008 
1009 /**
1010  * Pack a ProtobufCBinaryData and return the number of bytes written. The output
1011  * includes a length delimiter.
1012  *
1013  * \param bd
1014  *      ProtobufCBinaryData to encode.
1015  * \param[out] out
1016  *      Packed value.
1017  * \return
1018  *      Number of bytes written to `out`.
1019  */
1020 static inline size_t
binary_data_pack(const ProtobufCBinaryData * bd,uint8_t * out)1021 binary_data_pack(const ProtobufCBinaryData *bd, uint8_t *out)
1022 {
1023 	size_t len = bd->len;
1024 	size_t rv = uint32_pack(len, out);
1025 	memcpy(out + rv, bd->data, len);
1026 	return rv + len;
1027 }
1028 
1029 /**
1030  * Pack a ProtobufCMessage and return the number of bytes written. The output
1031  * includes a length delimiter.
1032  *
1033  * \param message
1034  *      ProtobufCMessage object to pack.
1035  * \param[out] out
1036  *      Packed message.
1037  * \return
1038  *      Number of bytes written to `out`.
1039  */
1040 static inline size_t
prefixed_message_pack(const ProtobufCMessage * message,uint8_t * out)1041 prefixed_message_pack(const ProtobufCMessage *message, uint8_t *out)
1042 {
1043 	if (message == NULL) {
1044 		out[0] = 0;
1045 		return 1;
1046 	} else {
1047 		size_t rv = protobuf_c_message_pack(message, out + 1);
1048 		uint32_t rv_packed_size = uint32_size(rv);
1049 		if (rv_packed_size != 1)
1050 			memmove(out + rv_packed_size, out + 1, rv);
1051 		return uint32_pack(rv, out) + rv;
1052 	}
1053 }
1054 
1055 /**
1056  * Pack a field tag.
1057  *
1058  * Wire-type will be added in required_field_pack().
1059  *
1060  * \todo Just call uint64_pack on 64-bit platforms.
1061  *
1062  * \param id
1063  *      Tag value to encode.
1064  * \param[out] out
1065  *      Packed value.
1066  * \return
1067  *      Number of bytes written to `out`.
1068  */
1069 static size_t
tag_pack(uint32_t id,uint8_t * out)1070 tag_pack(uint32_t id, uint8_t *out)
1071 {
1072 	if (id < (1UL << (32 - 3)))
1073 		return uint32_pack(id << 3, out);
1074 	else
1075 		return uint64_pack(((uint64_t) id) << 3, out);
1076 }
1077 
1078 /**
1079  * Pack a required field and return the number of bytes written.
1080  *
1081  * \param field
1082  *      Field descriptor.
1083  * \param member
1084  *      The field member.
1085  * \param[out] out
1086  *      Packed value.
1087  * \return
1088  *      Number of bytes written to `out`.
1089  */
1090 static size_t
required_field_pack(const ProtobufCFieldDescriptor * field,const void * member,uint8_t * out)1091 required_field_pack(const ProtobufCFieldDescriptor *field,
1092 		    const void *member, uint8_t *out)
1093 {
1094 	size_t rv = tag_pack(field->id, out);
1095 
1096 	switch (field->type) {
1097 	case PROTOBUF_C_TYPE_SINT32:
1098 		out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
1099 		return rv + sint32_pack(*(const int32_t *) member, out + rv);
1100 	case PROTOBUF_C_TYPE_ENUM:
1101 	case PROTOBUF_C_TYPE_INT32:
1102 		out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
1103 		return rv + int32_pack(*(const int32_t *) member, out + rv);
1104 	case PROTOBUF_C_TYPE_UINT32:
1105 		out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
1106 		return rv + uint32_pack(*(const uint32_t *) member, out + rv);
1107 	case PROTOBUF_C_TYPE_SINT64:
1108 		out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
1109 		return rv + sint64_pack(*(const int64_t *) member, out + rv);
1110 	case PROTOBUF_C_TYPE_INT64:
1111 	case PROTOBUF_C_TYPE_UINT64:
1112 		out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
1113 		return rv + uint64_pack(*(const uint64_t *) member, out + rv);
1114 	case PROTOBUF_C_TYPE_SFIXED32:
1115 	case PROTOBUF_C_TYPE_FIXED32:
1116 	case PROTOBUF_C_TYPE_FLOAT:
1117 		out[0] |= PROTOBUF_C_WIRE_TYPE_32BIT;
1118 		return rv + fixed32_pack(*(const uint32_t *) member, out + rv);
1119 	case PROTOBUF_C_TYPE_SFIXED64:
1120 	case PROTOBUF_C_TYPE_FIXED64:
1121 	case PROTOBUF_C_TYPE_DOUBLE:
1122 		out[0] |= PROTOBUF_C_WIRE_TYPE_64BIT;
1123 		return rv + fixed64_pack(*(const uint64_t *) member, out + rv);
1124 	case PROTOBUF_C_TYPE_BOOL:
1125 		out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
1126 		return rv + boolean_pack(*(const protobuf_c_boolean *) member, out + rv);
1127 	case PROTOBUF_C_TYPE_STRING:
1128 		out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
1129 		return rv + string_pack(*(char *const *) member, out + rv);
1130 	case PROTOBUF_C_TYPE_BYTES:
1131 		out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
1132 		return rv + binary_data_pack((const ProtobufCBinaryData *) member, out + rv);
1133 	case PROTOBUF_C_TYPE_MESSAGE:
1134 		out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
1135 		return rv + prefixed_message_pack(*(ProtobufCMessage * const *) member, out + rv);
1136 	}
1137 	PROTOBUF_C__ASSERT_NOT_REACHED();
1138 	return 0;
1139 }
1140 
1141 /**
1142  * Pack a oneof field and return the number of bytes written. Only packs the
1143  * field that is selected by the case enum.
1144  *
1145  * \param field
1146  *      Field descriptor.
1147  * \param oneof_case
1148  *      Enum value that selects the field in the oneof.
1149  * \param member
1150  *      The field member.
1151  * \param[out] out
1152  *      Packed value.
1153  * \return
1154  *      Number of bytes written to `out`.
1155  */
1156 static size_t
oneof_field_pack(const ProtobufCFieldDescriptor * field,uint32_t oneof_case,const void * member,uint8_t * out)1157 oneof_field_pack(const ProtobufCFieldDescriptor *field,
1158 		 uint32_t oneof_case,
1159 		 const void *member, uint8_t *out)
1160 {
1161 	if (oneof_case != field->id) {
1162 		return 0;
1163 	}
1164 	if (field->type == PROTOBUF_C_TYPE_MESSAGE ||
1165 	    field->type == PROTOBUF_C_TYPE_STRING)
1166 	{
1167 		const void *ptr = *(const void * const *) member;
1168 		if (ptr == NULL || ptr == field->default_value)
1169 			return 0;
1170 	}
1171 	return required_field_pack(field, member, out);
1172 }
1173 
1174 /**
1175  * Pack an optional field and return the number of bytes written.
1176  *
1177  * \param field
1178  *      Field descriptor.
1179  * \param has
1180  *      Whether the field is set.
1181  * \param member
1182  *      The field member.
1183  * \param[out] out
1184  *      Packed value.
1185  * \return
1186  *      Number of bytes written to `out`.
1187  */
1188 static size_t
optional_field_pack(const ProtobufCFieldDescriptor * field,const protobuf_c_boolean has,const void * member,uint8_t * out)1189 optional_field_pack(const ProtobufCFieldDescriptor *field,
1190 		    const protobuf_c_boolean has,
1191 		    const void *member, uint8_t *out)
1192 {
1193 	if (field->type == PROTOBUF_C_TYPE_MESSAGE ||
1194 	    field->type == PROTOBUF_C_TYPE_STRING)
1195 	{
1196 		const void *ptr = *(const void * const *) member;
1197 		if (ptr == NULL || ptr == field->default_value)
1198 			return 0;
1199 	} else {
1200 		if (!has)
1201 			return 0;
1202 	}
1203 	return required_field_pack(field, member, out);
1204 }
1205 
1206 /**
1207  * Pack an unlabeled field and return the number of bytes written.
1208  *
1209  * \param field
1210  *      Field descriptor.
1211  * \param member
1212  *      The field member.
1213  * \param[out] out
1214  *      Packed value.
1215  * \return
1216  *      Number of bytes written to `out`.
1217  */
1218 static size_t
unlabeled_field_pack(const ProtobufCFieldDescriptor * field,const void * member,uint8_t * out)1219 unlabeled_field_pack(const ProtobufCFieldDescriptor *field,
1220 		     const void *member, uint8_t *out)
1221 {
1222 	if (field_is_zeroish(field, member))
1223 		return 0;
1224 	return required_field_pack(field, member, out);
1225 }
1226 
1227 /**
1228  * Given a field type, return the in-memory size.
1229  *
1230  * \todo Implement as a table lookup.
1231  *
1232  * \param type
1233  *      Field type.
1234  * \return
1235  *      Size of the field.
1236  */
1237 static inline size_t
sizeof_elt_in_repeated_array(ProtobufCType type)1238 sizeof_elt_in_repeated_array(ProtobufCType type)
1239 {
1240 	switch (type) {
1241 	case PROTOBUF_C_TYPE_SINT32:
1242 	case PROTOBUF_C_TYPE_INT32:
1243 	case PROTOBUF_C_TYPE_UINT32:
1244 	case PROTOBUF_C_TYPE_SFIXED32:
1245 	case PROTOBUF_C_TYPE_FIXED32:
1246 	case PROTOBUF_C_TYPE_FLOAT:
1247 	case PROTOBUF_C_TYPE_ENUM:
1248 		return 4;
1249 	case PROTOBUF_C_TYPE_SINT64:
1250 	case PROTOBUF_C_TYPE_INT64:
1251 	case PROTOBUF_C_TYPE_UINT64:
1252 	case PROTOBUF_C_TYPE_SFIXED64:
1253 	case PROTOBUF_C_TYPE_FIXED64:
1254 	case PROTOBUF_C_TYPE_DOUBLE:
1255 		return 8;
1256 	case PROTOBUF_C_TYPE_BOOL:
1257 		return sizeof(protobuf_c_boolean);
1258 	case PROTOBUF_C_TYPE_STRING:
1259 	case PROTOBUF_C_TYPE_MESSAGE:
1260 		return sizeof(void *);
1261 	case PROTOBUF_C_TYPE_BYTES:
1262 		return sizeof(ProtobufCBinaryData);
1263 	}
1264 	PROTOBUF_C__ASSERT_NOT_REACHED();
1265 	return 0;
1266 }
1267 
1268 /**
1269  * Pack an array of 32-bit quantities.
1270  *
1271  * \param[out] out
1272  *      Destination.
1273  * \param[in] in
1274  *      Source.
1275  * \param[in] n
1276  *      Number of elements in the source array.
1277  */
1278 static void
copy_to_little_endian_32(void * out,const void * in,const unsigned n)1279 copy_to_little_endian_32(void *out, const void *in, const unsigned n)
1280 {
1281 #if !defined(WORDS_BIGENDIAN)
1282 	memcpy(out, in, n * 4);
1283 #else
1284 	unsigned i;
1285 	const uint32_t *ini = in;
1286 	for (i = 0; i < n; i++)
1287 		fixed32_pack(ini[i], (uint32_t *) out + i);
1288 #endif
1289 }
1290 
1291 /**
1292  * Pack an array of 64-bit quantities.
1293  *
1294  * \param[out] out
1295  *      Destination.
1296  * \param[in] in
1297  *      Source.
1298  * \param[in] n
1299  *      Number of elements in the source array.
1300  */
1301 static void
copy_to_little_endian_64(void * out,const void * in,const unsigned n)1302 copy_to_little_endian_64(void *out, const void *in, const unsigned n)
1303 {
1304 #if !defined(WORDS_BIGENDIAN)
1305 	memcpy(out, in, n * 8);
1306 #else
1307 	unsigned i;
1308 	const uint64_t *ini = in;
1309 	for (i = 0; i < n; i++)
1310 		fixed64_pack(ini[i], (uint64_t *) out + i);
1311 #endif
1312 }
1313 
1314 /**
1315  * Get the minimum number of bytes required to pack a field value of a
1316  * particular type.
1317  *
1318  * \param type
1319  *      Field type.
1320  * \return
1321  *      Number of bytes.
1322  */
1323 static unsigned
get_type_min_size(ProtobufCType type)1324 get_type_min_size(ProtobufCType type)
1325 {
1326 	if (type == PROTOBUF_C_TYPE_SFIXED32 ||
1327 	    type == PROTOBUF_C_TYPE_FIXED32 ||
1328 	    type == PROTOBUF_C_TYPE_FLOAT)
1329 	{
1330 		return 4;
1331 	}
1332 	if (type == PROTOBUF_C_TYPE_SFIXED64 ||
1333 	    type == PROTOBUF_C_TYPE_FIXED64 ||
1334 	    type == PROTOBUF_C_TYPE_DOUBLE)
1335 	{
1336 		return 8;
1337 	}
1338 	return 1;
1339 }
1340 
1341 /**
1342  * Packs the elements of a repeated field and returns the serialised field and
1343  * its length.
1344  *
1345  * \param field
1346  *      Field descriptor.
1347  * \param count
1348  *      Number of elements in the repeated field array.
1349  * \param member
1350  *      Pointer to the elements for this repeated field.
1351  * \param[out] out
1352  *      Serialised representation of the repeated field.
1353  * \return
1354  *      Number of bytes serialised to `out`.
1355  */
1356 static size_t
repeated_field_pack(const ProtobufCFieldDescriptor * field,size_t count,const void * member,uint8_t * out)1357 repeated_field_pack(const ProtobufCFieldDescriptor *field,
1358 		    size_t count, const void *member, uint8_t *out)
1359 {
1360 	void *array = *(void * const *) member;
1361 	unsigned i;
1362 
1363 	if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED)) {
1364 		unsigned header_len;
1365 		unsigned len_start;
1366 		unsigned min_length;
1367 		unsigned payload_len;
1368 		unsigned length_size_min;
1369 		unsigned actual_length_size;
1370 		uint8_t *payload_at;
1371 
1372 		if (count == 0)
1373 			return 0;
1374 		header_len = tag_pack(field->id, out);
1375 		out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
1376 		len_start = header_len;
1377 		min_length = get_type_min_size(field->type) * count;
1378 		length_size_min = uint32_size(min_length);
1379 		header_len += length_size_min;
1380 		payload_at = out + header_len;
1381 
1382 		switch (field->type) {
1383 		case PROTOBUF_C_TYPE_SFIXED32:
1384 		case PROTOBUF_C_TYPE_FIXED32:
1385 		case PROTOBUF_C_TYPE_FLOAT:
1386 			copy_to_little_endian_32(payload_at, array, count);
1387 			payload_at += count * 4;
1388 			break;
1389 		case PROTOBUF_C_TYPE_SFIXED64:
1390 		case PROTOBUF_C_TYPE_FIXED64:
1391 		case PROTOBUF_C_TYPE_DOUBLE:
1392 			copy_to_little_endian_64(payload_at, array, count);
1393 			payload_at += count * 8;
1394 			break;
1395 		case PROTOBUF_C_TYPE_ENUM:
1396 		case PROTOBUF_C_TYPE_INT32: {
1397 			const int32_t *arr = (const int32_t *) array;
1398 			for (i = 0; i < count; i++)
1399 				payload_at += int32_pack(arr[i], payload_at);
1400 			break;
1401 		}
1402 		case PROTOBUF_C_TYPE_SINT32: {
1403 			const int32_t *arr = (const int32_t *) array;
1404 			for (i = 0; i < count; i++)
1405 				payload_at += sint32_pack(arr[i], payload_at);
1406 			break;
1407 		}
1408 		case PROTOBUF_C_TYPE_SINT64: {
1409 			const int64_t *arr = (const int64_t *) array;
1410 			for (i = 0; i < count; i++)
1411 				payload_at += sint64_pack(arr[i], payload_at);
1412 			break;
1413 		}
1414 		case PROTOBUF_C_TYPE_UINT32: {
1415 			const uint32_t *arr = (const uint32_t *) array;
1416 			for (i = 0; i < count; i++)
1417 				payload_at += uint32_pack(arr[i], payload_at);
1418 			break;
1419 		}
1420 		case PROTOBUF_C_TYPE_INT64:
1421 		case PROTOBUF_C_TYPE_UINT64: {
1422 			const uint64_t *arr = (const uint64_t *) array;
1423 			for (i = 0; i < count; i++)
1424 				payload_at += uint64_pack(arr[i], payload_at);
1425 			break;
1426 		}
1427 		case PROTOBUF_C_TYPE_BOOL: {
1428 			const protobuf_c_boolean *arr = (const protobuf_c_boolean *) array;
1429 			for (i = 0; i < count; i++)
1430 				payload_at += boolean_pack(arr[i], payload_at);
1431 			break;
1432 		}
1433 		default:
1434 			PROTOBUF_C__ASSERT_NOT_REACHED();
1435 		}
1436 
1437 		payload_len = payload_at - (out + header_len);
1438 		actual_length_size = uint32_size(payload_len);
1439 		if (length_size_min != actual_length_size) {
1440 			assert(actual_length_size == length_size_min + 1);
1441 			memmove(out + header_len + 1, out + header_len,
1442 				payload_len);
1443 			header_len++;
1444 		}
1445 		uint32_pack(payload_len, out + len_start);
1446 		return header_len + payload_len;
1447 	} else {
1448 		/* not "packed" cased */
1449 		/* CONSIDER: optimize this case a bit (by putting the loop inside the switch) */
1450 		size_t rv = 0;
1451 		unsigned siz = sizeof_elt_in_repeated_array(field->type);
1452 
1453 		for (i = 0; i < count; i++) {
1454 			rv += required_field_pack(field, array, out + rv);
1455 			array = (char *)array + siz;
1456 		}
1457 		return rv;
1458 	}
1459 }
1460 
1461 static size_t
unknown_field_pack(const ProtobufCMessageUnknownField * field,uint8_t * out)1462 unknown_field_pack(const ProtobufCMessageUnknownField *field, uint8_t *out)
1463 {
1464 	size_t rv = tag_pack(field->tag, out);
1465 	out[0] |= field->wire_type;
1466 	memcpy(out + rv, field->data, field->len);
1467 	return rv + field->len;
1468 }
1469 
1470 /**@}*/
1471 
1472 size_t
protobuf_c_message_pack(const ProtobufCMessage * message,uint8_t * out)1473 protobuf_c_message_pack(const ProtobufCMessage *message, uint8_t *out)
1474 {
1475 	unsigned i;
1476 	size_t rv = 0;
1477 
1478 	ASSERT_IS_MESSAGE(message);
1479 	for (i = 0; i < message->descriptor->n_fields; i++) {
1480 		const ProtobufCFieldDescriptor *field =
1481 			message->descriptor->fields + i;
1482 		const void *member = ((const char *) message) + field->offset;
1483 
1484 		/*
1485 		 * It doesn't hurt to compute qmember (a pointer to the
1486 		 * quantifier field of the structure), but the pointer is only
1487 		 * valid if the field is:
1488 		 *  - a repeated field, or
1489 		 *  - a field that is part of a oneof
1490 		 *  - an optional field that isn't a pointer type
1491 		 * (Meaning: not a message or a string).
1492 		 */
1493 		const void *qmember =
1494 			((const char *) message) + field->quantifier_offset;
1495 
1496 		if (field->label == PROTOBUF_C_LABEL_REQUIRED) {
1497 			rv += required_field_pack(field, member, out + rv);
1498 		} else if ((field->label == PROTOBUF_C_LABEL_OPTIONAL ||
1499 			    field->label == PROTOBUF_C_LABEL_NONE) &&
1500 			   (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF))) {
1501 			rv += oneof_field_pack(
1502 				field,
1503 				*(const uint32_t *) qmember,
1504 				member,
1505 				out + rv
1506 			);
1507 		} else if (field->label == PROTOBUF_C_LABEL_OPTIONAL) {
1508 			rv += optional_field_pack(
1509 				field,
1510 				*(const protobuf_c_boolean *) qmember,
1511 				member,
1512 				out + rv
1513 			);
1514 		} else if (field->label == PROTOBUF_C_LABEL_NONE) {
1515 			rv += unlabeled_field_pack(field, member, out + rv);
1516 		} else {
1517 			rv += repeated_field_pack(field, *(const size_t *) qmember,
1518 				member, out + rv);
1519 		}
1520 	}
1521 	for (i = 0; i < message->n_unknown_fields; i++)
1522 		rv += unknown_field_pack(&message->unknown_fields[i], out + rv);
1523 	return rv;
1524 }
1525 
1526 /**
1527  * \defgroup packbuf protobuf_c_message_pack_to_buffer() implementation
1528  *
1529  * Routines mainly used by protobuf_c_message_pack_to_buffer().
1530  *
1531  * \ingroup internal
1532  * @{
1533  */
1534 
1535 /**
1536  * Pack a required field to a virtual buffer.
1537  *
1538  * \param field
1539  *      Field descriptor.
1540  * \param member
1541  *      The element to be packed.
1542  * \param[out] buffer
1543  *      Virtual buffer to append data to.
1544  * \return
1545  *      Number of bytes packed.
1546  */
1547 static size_t
required_field_pack_to_buffer(const ProtobufCFieldDescriptor * field,const void * member,ProtobufCBuffer * buffer)1548 required_field_pack_to_buffer(const ProtobufCFieldDescriptor *field,
1549 			      const void *member, ProtobufCBuffer *buffer)
1550 {
1551 	size_t rv;
1552 	uint8_t scratch[MAX_UINT64_ENCODED_SIZE * 2];
1553 
1554 	rv = tag_pack(field->id, scratch);
1555 	switch (field->type) {
1556 	case PROTOBUF_C_TYPE_SINT32:
1557 		scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
1558 		rv += sint32_pack(*(const int32_t *) member, scratch + rv);
1559 		buffer->append(buffer, rv, scratch);
1560 		break;
1561 	case PROTOBUF_C_TYPE_ENUM:
1562 	case PROTOBUF_C_TYPE_INT32:
1563 		scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
1564 		rv += int32_pack(*(const int32_t *) member, scratch + rv);
1565 		buffer->append(buffer, rv, scratch);
1566 		break;
1567 	case PROTOBUF_C_TYPE_UINT32:
1568 		scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
1569 		rv += uint32_pack(*(const uint32_t *) member, scratch + rv);
1570 		buffer->append(buffer, rv, scratch);
1571 		break;
1572 	case PROTOBUF_C_TYPE_SINT64:
1573 		scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
1574 		rv += sint64_pack(*(const int64_t *) member, scratch + rv);
1575 		buffer->append(buffer, rv, scratch);
1576 		break;
1577 	case PROTOBUF_C_TYPE_INT64:
1578 	case PROTOBUF_C_TYPE_UINT64:
1579 		scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
1580 		rv += uint64_pack(*(const uint64_t *) member, scratch + rv);
1581 		buffer->append(buffer, rv, scratch);
1582 		break;
1583 	case PROTOBUF_C_TYPE_SFIXED32:
1584 	case PROTOBUF_C_TYPE_FIXED32:
1585 	case PROTOBUF_C_TYPE_FLOAT:
1586 		scratch[0] |= PROTOBUF_C_WIRE_TYPE_32BIT;
1587 		rv += fixed32_pack(*(const uint32_t *) member, scratch + rv);
1588 		buffer->append(buffer, rv, scratch);
1589 		break;
1590 	case PROTOBUF_C_TYPE_SFIXED64:
1591 	case PROTOBUF_C_TYPE_FIXED64:
1592 	case PROTOBUF_C_TYPE_DOUBLE:
1593 		scratch[0] |= PROTOBUF_C_WIRE_TYPE_64BIT;
1594 		rv += fixed64_pack(*(const uint64_t *) member, scratch + rv);
1595 		buffer->append(buffer, rv, scratch);
1596 		break;
1597 	case PROTOBUF_C_TYPE_BOOL:
1598 		scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
1599 		rv += boolean_pack(*(const protobuf_c_boolean *) member, scratch + rv);
1600 		buffer->append(buffer, rv, scratch);
1601 		break;
1602 	case PROTOBUF_C_TYPE_STRING: {
1603 		const char *str = *(char *const *) member;
1604 		size_t sublen = str ? strlen(str) : 0;
1605 
1606 		scratch[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
1607 		rv += uint32_pack(sublen, scratch + rv);
1608 		buffer->append(buffer, rv, scratch);
1609 		buffer->append(buffer, sublen, (const uint8_t *) str);
1610 		rv += sublen;
1611 		break;
1612 	}
1613 	case PROTOBUF_C_TYPE_BYTES: {
1614 		const ProtobufCBinaryData *bd = ((const ProtobufCBinaryData *) member);
1615 		size_t sublen = bd->len;
1616 
1617 		scratch[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
1618 		rv += uint32_pack(sublen, scratch + rv);
1619 		buffer->append(buffer, rv, scratch);
1620 		buffer->append(buffer, sublen, bd->data);
1621 		rv += sublen;
1622 		break;
1623 	}
1624 	case PROTOBUF_C_TYPE_MESSAGE: {
1625 		const ProtobufCMessage *msg = *(ProtobufCMessage * const *) member;
1626 
1627 		scratch[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
1628 		if (msg == NULL) {
1629 			rv += uint32_pack(0, scratch + rv);
1630 			buffer->append(buffer, rv, scratch);
1631 		} else {
1632 			size_t sublen = protobuf_c_message_get_packed_size(msg);
1633 			rv += uint32_pack(sublen, scratch + rv);
1634 			buffer->append(buffer, rv, scratch);
1635 			protobuf_c_message_pack_to_buffer(msg, buffer);
1636 			rv += sublen;
1637 		}
1638 		break;
1639 	}
1640 	default:
1641 		PROTOBUF_C__ASSERT_NOT_REACHED();
1642 	}
1643 	return rv;
1644 }
1645 
1646 /**
1647  * Pack a oneof field to a buffer. Only packs the field that is selected by the case enum.
1648  *
1649  * \param field
1650  *      Field descriptor.
1651  * \param oneof_case
1652  *      Enum value that selects the field in the oneof.
1653  * \param member
1654  *      The element to be packed.
1655  * \param[out] buffer
1656  *      Virtual buffer to append data to.
1657  * \return
1658  *      Number of bytes serialised to `buffer`.
1659  */
1660 static size_t
oneof_field_pack_to_buffer(const ProtobufCFieldDescriptor * field,uint32_t oneof_case,const void * member,ProtobufCBuffer * buffer)1661 oneof_field_pack_to_buffer(const ProtobufCFieldDescriptor *field,
1662 			   uint32_t oneof_case,
1663 			   const void *member, ProtobufCBuffer *buffer)
1664 {
1665 	if (oneof_case != field->id) {
1666 		return 0;
1667 	}
1668 	if (field->type == PROTOBUF_C_TYPE_MESSAGE ||
1669 	    field->type == PROTOBUF_C_TYPE_STRING)
1670 	{
1671 		const void *ptr = *(const void *const *) member;
1672 		if (ptr == NULL || ptr == field->default_value)
1673 			return 0;
1674 	}
1675 	return required_field_pack_to_buffer(field, member, buffer);
1676 }
1677 
1678 /**
1679  * Pack an optional field to a buffer.
1680  *
1681  * \param field
1682  *      Field descriptor.
1683  * \param has
1684  *      Whether the field is set.
1685  * \param member
1686  *      The element to be packed.
1687  * \param[out] buffer
1688  *      Virtual buffer to append data to.
1689  * \return
1690  *      Number of bytes serialised to `buffer`.
1691  */
1692 static size_t
optional_field_pack_to_buffer(const ProtobufCFieldDescriptor * field,const protobuf_c_boolean has,const void * member,ProtobufCBuffer * buffer)1693 optional_field_pack_to_buffer(const ProtobufCFieldDescriptor *field,
1694 			      const protobuf_c_boolean has,
1695 			      const void *member, ProtobufCBuffer *buffer)
1696 {
1697 	if (field->type == PROTOBUF_C_TYPE_MESSAGE ||
1698 	    field->type == PROTOBUF_C_TYPE_STRING)
1699 	{
1700 		const void *ptr = *(const void *const *) member;
1701 		if (ptr == NULL || ptr == field->default_value)
1702 			return 0;
1703 	} else {
1704 		if (!has)
1705 			return 0;
1706 	}
1707 	return required_field_pack_to_buffer(field, member, buffer);
1708 }
1709 
1710 /**
1711  * Pack an unlabeled field to a buffer.
1712  *
1713  * \param field
1714  *      Field descriptor.
1715  * \param member
1716  *      The element to be packed.
1717  * \param[out] buffer
1718  *      Virtual buffer to append data to.
1719  * \return
1720  *      Number of bytes serialised to `buffer`.
1721  */
1722 static size_t
unlabeled_field_pack_to_buffer(const ProtobufCFieldDescriptor * field,const void * member,ProtobufCBuffer * buffer)1723 unlabeled_field_pack_to_buffer(const ProtobufCFieldDescriptor *field,
1724 			       const void *member, ProtobufCBuffer *buffer)
1725 {
1726 	if (field_is_zeroish(field, member))
1727 		return 0;
1728 	return required_field_pack_to_buffer(field, member, buffer);
1729 }
1730 
1731 /**
1732  * Get the packed size of an array of same field type.
1733  *
1734  * \param field
1735  *      Field descriptor.
1736  * \param count
1737  *      Number of elements of this type.
1738  * \param array
1739  *      The elements to get the size of.
1740  * \return
1741  *      Number of bytes required.
1742  */
1743 static size_t
get_packed_payload_length(const ProtobufCFieldDescriptor * field,unsigned count,const void * array)1744 get_packed_payload_length(const ProtobufCFieldDescriptor *field,
1745 			  unsigned count, const void *array)
1746 {
1747 	unsigned rv = 0;
1748 	unsigned i;
1749 
1750 	switch (field->type) {
1751 	case PROTOBUF_C_TYPE_SFIXED32:
1752 	case PROTOBUF_C_TYPE_FIXED32:
1753 	case PROTOBUF_C_TYPE_FLOAT:
1754 		return count * 4;
1755 	case PROTOBUF_C_TYPE_SFIXED64:
1756 	case PROTOBUF_C_TYPE_FIXED64:
1757 	case PROTOBUF_C_TYPE_DOUBLE:
1758 		return count * 8;
1759 	case PROTOBUF_C_TYPE_ENUM:
1760 	case PROTOBUF_C_TYPE_INT32: {
1761 		const int32_t *arr = (const int32_t *) array;
1762 		for (i = 0; i < count; i++)
1763 			rv += int32_size(arr[i]);
1764 		break;
1765 	}
1766 	case PROTOBUF_C_TYPE_SINT32: {
1767 		const int32_t *arr = (const int32_t *) array;
1768 		for (i = 0; i < count; i++)
1769 			rv += sint32_size(arr[i]);
1770 		break;
1771 	}
1772 	case PROTOBUF_C_TYPE_UINT32: {
1773 		const uint32_t *arr = (const uint32_t *) array;
1774 		for (i = 0; i < count; i++)
1775 			rv += uint32_size(arr[i]);
1776 		break;
1777 	}
1778 	case PROTOBUF_C_TYPE_SINT64: {
1779 		const int64_t *arr = (const int64_t *) array;
1780 		for (i = 0; i < count; i++)
1781 			rv += sint64_size(arr[i]);
1782 		break;
1783 	}
1784 	case PROTOBUF_C_TYPE_INT64:
1785 	case PROTOBUF_C_TYPE_UINT64: {
1786 		const uint64_t *arr = (const uint64_t *) array;
1787 		for (i = 0; i < count; i++)
1788 			rv += uint64_size(arr[i]);
1789 		break;
1790 	}
1791 	case PROTOBUF_C_TYPE_BOOL:
1792 		return count;
1793 	default:
1794 		PROTOBUF_C__ASSERT_NOT_REACHED();
1795 	}
1796 	return rv;
1797 }
1798 
1799 /**
1800  * Pack an array of same field type to a virtual buffer.
1801  *
1802  * \param field
1803  *      Field descriptor.
1804  * \param count
1805  *      Number of elements of this type.
1806  * \param array
1807  *      The elements to get the size of.
1808  * \param[out] buffer
1809  *      Virtual buffer to append data to.
1810  * \return
1811  *      Number of bytes packed.
1812  */
1813 static size_t
pack_buffer_packed_payload(const ProtobufCFieldDescriptor * field,unsigned count,const void * array,ProtobufCBuffer * buffer)1814 pack_buffer_packed_payload(const ProtobufCFieldDescriptor *field,
1815 			   unsigned count, const void *array,
1816 			   ProtobufCBuffer *buffer)
1817 {
1818 	uint8_t scratch[16];
1819 	size_t rv = 0;
1820 	unsigned i;
1821 
1822 	switch (field->type) {
1823 	case PROTOBUF_C_TYPE_SFIXED32:
1824 	case PROTOBUF_C_TYPE_FIXED32:
1825 	case PROTOBUF_C_TYPE_FLOAT:
1826 #if !defined(WORDS_BIGENDIAN)
1827 		rv = count * 4;
1828 		goto no_packing_needed;
1829 #else
1830 		for (i = 0; i < count; i++) {
1831 			unsigned len = fixed32_pack(((uint32_t *) array)[i], scratch);
1832 			buffer->append(buffer, len, scratch);
1833 			rv += len;
1834 		}
1835 		break;
1836 #endif
1837 	case PROTOBUF_C_TYPE_SFIXED64:
1838 	case PROTOBUF_C_TYPE_FIXED64:
1839 	case PROTOBUF_C_TYPE_DOUBLE:
1840 #if !defined(WORDS_BIGENDIAN)
1841 		rv = count * 8;
1842 		goto no_packing_needed;
1843 #else
1844 		for (i = 0; i < count; i++) {
1845 			unsigned len = fixed64_pack(((uint64_t *) array)[i], scratch);
1846 			buffer->append(buffer, len, scratch);
1847 			rv += len;
1848 		}
1849 		break;
1850 #endif
1851 	case PROTOBUF_C_TYPE_ENUM:
1852 	case PROTOBUF_C_TYPE_INT32:
1853 		for (i = 0; i < count; i++) {
1854 			unsigned len = int32_pack(((int32_t *) array)[i], scratch);
1855 			buffer->append(buffer, len, scratch);
1856 			rv += len;
1857 		}
1858 		break;
1859 	case PROTOBUF_C_TYPE_SINT32:
1860 		for (i = 0; i < count; i++) {
1861 			unsigned len = sint32_pack(((int32_t *) array)[i], scratch);
1862 			buffer->append(buffer, len, scratch);
1863 			rv += len;
1864 		}
1865 		break;
1866 	case PROTOBUF_C_TYPE_UINT32:
1867 		for (i = 0; i < count; i++) {
1868 			unsigned len = uint32_pack(((uint32_t *) array)[i], scratch);
1869 			buffer->append(buffer, len, scratch);
1870 			rv += len;
1871 		}
1872 		break;
1873 	case PROTOBUF_C_TYPE_SINT64:
1874 		for (i = 0; i < count; i++) {
1875 			unsigned len = sint64_pack(((int64_t *) array)[i], scratch);
1876 			buffer->append(buffer, len, scratch);
1877 			rv += len;
1878 		}
1879 		break;
1880 	case PROTOBUF_C_TYPE_INT64:
1881 	case PROTOBUF_C_TYPE_UINT64:
1882 		for (i = 0; i < count; i++) {
1883 			unsigned len = uint64_pack(((uint64_t *) array)[i], scratch);
1884 			buffer->append(buffer, len, scratch);
1885 			rv += len;
1886 		}
1887 		break;
1888 	case PROTOBUF_C_TYPE_BOOL:
1889 		for (i = 0; i < count; i++) {
1890 			unsigned len = boolean_pack(((protobuf_c_boolean *) array)[i], scratch);
1891 			buffer->append(buffer, len, scratch);
1892 			rv += len;
1893 		}
1894 		return count;
1895 	default:
1896 		PROTOBUF_C__ASSERT_NOT_REACHED();
1897 	}
1898 	return rv;
1899 
1900 #if !defined(WORDS_BIGENDIAN)
1901 no_packing_needed:
1902 	buffer->append(buffer, rv, array);
1903 	return rv;
1904 #endif
1905 }
1906 
1907 static size_t
repeated_field_pack_to_buffer(const ProtobufCFieldDescriptor * field,unsigned count,const void * member,ProtobufCBuffer * buffer)1908 repeated_field_pack_to_buffer(const ProtobufCFieldDescriptor *field,
1909 			      unsigned count, const void *member,
1910 			      ProtobufCBuffer *buffer)
1911 {
1912 	char *array = *(char * const *) member;
1913 
1914 	if (count == 0)
1915 		return 0;
1916 	if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED)) {
1917 		uint8_t scratch[MAX_UINT64_ENCODED_SIZE * 2];
1918 		size_t rv = tag_pack(field->id, scratch);
1919 		size_t payload_len = get_packed_payload_length(field, count, array);
1920 		size_t tmp;
1921 
1922 		scratch[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
1923 		rv += uint32_pack(payload_len, scratch + rv);
1924 		buffer->append(buffer, rv, scratch);
1925 		tmp = pack_buffer_packed_payload(field, count, array, buffer);
1926 		assert(tmp == payload_len);
1927 		return rv + payload_len;
1928 	} else {
1929 		size_t siz;
1930 		unsigned i;
1931 		/* CONSIDER: optimize this case a bit (by putting the loop inside the switch) */
1932 		unsigned rv = 0;
1933 
1934 		siz = sizeof_elt_in_repeated_array(field->type);
1935 		for (i = 0; i < count; i++) {
1936 			rv += required_field_pack_to_buffer(field, array, buffer);
1937 			array += siz;
1938 		}
1939 		return rv;
1940 	}
1941 }
1942 
1943 static size_t
unknown_field_pack_to_buffer(const ProtobufCMessageUnknownField * field,ProtobufCBuffer * buffer)1944 unknown_field_pack_to_buffer(const ProtobufCMessageUnknownField *field,
1945 			     ProtobufCBuffer *buffer)
1946 {
1947 	uint8_t header[MAX_UINT64_ENCODED_SIZE];
1948 	size_t rv = tag_pack(field->tag, header);
1949 
1950 	header[0] |= field->wire_type;
1951 	buffer->append(buffer, rv, header);
1952 	buffer->append(buffer, field->len, field->data);
1953 	return rv + field->len;
1954 }
1955 
1956 /**@}*/
1957 
1958 size_t
protobuf_c_message_pack_to_buffer(const ProtobufCMessage * message,ProtobufCBuffer * buffer)1959 protobuf_c_message_pack_to_buffer(const ProtobufCMessage *message,
1960 				  ProtobufCBuffer *buffer)
1961 {
1962 	unsigned i;
1963 	size_t rv = 0;
1964 
1965 	ASSERT_IS_MESSAGE(message);
1966 	for (i = 0; i < message->descriptor->n_fields; i++) {
1967 		const ProtobufCFieldDescriptor *field =
1968 			message->descriptor->fields + i;
1969 		const void *member =
1970 			((const char *) message) + field->offset;
1971 		const void *qmember =
1972 			((const char *) message) + field->quantifier_offset;
1973 
1974 		if (field->label == PROTOBUF_C_LABEL_REQUIRED) {
1975 			rv += required_field_pack_to_buffer(field, member, buffer);
1976 		} else if ((field->label == PROTOBUF_C_LABEL_OPTIONAL ||
1977 			    field->label == PROTOBUF_C_LABEL_NONE) &&
1978 			   (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF))) {
1979 			rv += oneof_field_pack_to_buffer(
1980 				field,
1981 				*(const uint32_t *) qmember,
1982 				member,
1983 				buffer
1984 			);
1985 		} else if (field->label == PROTOBUF_C_LABEL_OPTIONAL) {
1986 			rv += optional_field_pack_to_buffer(
1987 				field,
1988 				*(const protobuf_c_boolean *) qmember,
1989 				member,
1990 				buffer
1991 			);
1992 		} else if (field->label == PROTOBUF_C_LABEL_NONE) {
1993 			rv += unlabeled_field_pack_to_buffer(
1994 				field,
1995 				member,
1996 				buffer
1997 			);
1998 		} else {
1999 			rv += repeated_field_pack_to_buffer(
2000 				field,
2001 				*(const size_t *) qmember,
2002 				member,
2003 				buffer
2004 			);
2005 		}
2006 	}
2007 	for (i = 0; i < message->n_unknown_fields; i++)
2008 		rv += unknown_field_pack_to_buffer(&message->unknown_fields[i], buffer);
2009 
2010 	return rv;
2011 }
2012 
2013 /**
2014  * \defgroup unpack unpacking implementation
2015  *
2016  * Routines mainly used by the unpacking functions.
2017  *
2018  * \ingroup internal
2019  * @{
2020  */
2021 
2022 static inline int
int_range_lookup(unsigned n_ranges,const ProtobufCIntRange * ranges,int value)2023 int_range_lookup(unsigned n_ranges, const ProtobufCIntRange *ranges, int value)
2024 {
2025 	unsigned n;
2026 	unsigned start;
2027 
2028 	if (n_ranges == 0)
2029 		return -1;
2030 	start = 0;
2031 	n = n_ranges;
2032 	while (n > 1) {
2033 		unsigned mid = start + n / 2;
2034 
2035 		if (value < ranges[mid].start_value) {
2036 			n = mid - start;
2037 		} else if (value >= ranges[mid].start_value +
2038 			   (int) (ranges[mid + 1].orig_index -
2039 				  ranges[mid].orig_index))
2040 		{
2041 			unsigned new_start = mid + 1;
2042 			n = start + n - new_start;
2043 			start = new_start;
2044 		} else
2045 			return (value - ranges[mid].start_value) +
2046 			    ranges[mid].orig_index;
2047 	}
2048 	if (n > 0) {
2049 		unsigned start_orig_index = ranges[start].orig_index;
2050 		unsigned range_size =
2051 			ranges[start + 1].orig_index - start_orig_index;
2052 
2053 		if (ranges[start].start_value <= value &&
2054 		    value < (int) (ranges[start].start_value + range_size))
2055 		{
2056 			return (value - ranges[start].start_value) +
2057 			    start_orig_index;
2058 		}
2059 	}
2060 	return -1;
2061 }
2062 
2063 static size_t
parse_tag_and_wiretype(size_t len,const uint8_t * data,uint32_t * tag_out,uint8_t * wiretype_out)2064 parse_tag_and_wiretype(size_t len,
2065 		       const uint8_t *data,
2066 		       uint32_t *tag_out,
2067 		       uint8_t *wiretype_out)
2068 {
2069 	unsigned max_rv = len > 5 ? 5 : len;
2070 	uint32_t tag = (data[0] & 0x7f) >> 3;
2071 	unsigned shift = 4;
2072 	unsigned rv;
2073 
2074 	/* 0 is not a valid tag value */
2075 	if ((data[0] & 0xf8) == 0) {
2076 		return 0;
2077 	}
2078 
2079 	*wiretype_out = data[0] & 7;
2080 	if ((data[0] & 0x80) == 0) {
2081 		*tag_out = tag;
2082 		return 1;
2083 	}
2084 	for (rv = 1; rv < max_rv; rv++) {
2085 		if (data[rv] & 0x80) {
2086 			tag |= (data[rv] & 0x7f) << shift;
2087 			shift += 7;
2088 		} else {
2089 			tag |= data[rv] << shift;
2090 			*tag_out = tag;
2091 			return rv + 1;
2092 		}
2093 	}
2094 	return 0; /* error: bad header */
2095 }
2096 
2097 /* sizeof(ScannedMember) must be <= (1UL<<BOUND_SIZEOF_SCANNED_MEMBER_LOG2) */
2098 #define BOUND_SIZEOF_SCANNED_MEMBER_LOG2 5
2099 typedef struct ScannedMember ScannedMember;
2100 /** Field as it's being read. */
2101 struct ScannedMember {
2102 	uint32_t tag;              /**< Field tag. */
2103 	uint8_t wire_type;         /**< Field type. */
2104 	uint8_t length_prefix_len; /**< Prefix length. */
2105 	const ProtobufCFieldDescriptor *field; /**< Field descriptor. */
2106 	size_t len;                /**< Field length. */
2107 	const uint8_t *data;       /**< Pointer to field data. */
2108 };
2109 
2110 static inline size_t
scan_length_prefixed_data(size_t len,const uint8_t * data,size_t * prefix_len_out)2111 scan_length_prefixed_data(size_t len, const uint8_t *data,
2112 			  size_t *prefix_len_out)
2113 {
2114 	unsigned hdr_max = len < 5 ? len : 5;
2115 	unsigned hdr_len;
2116 	size_t val = 0;
2117 	unsigned i;
2118 	unsigned shift = 0;
2119 
2120 	for (i = 0; i < hdr_max; i++) {
2121 		val |= ((size_t)data[i] & 0x7f) << shift;
2122 		shift += 7;
2123 		if ((data[i] & 0x80) == 0)
2124 			break;
2125 	}
2126 	if (i == hdr_max) {
2127 		PROTOBUF_C_UNPACK_ERROR("error parsing length for length-prefixed data");
2128 		return 0;
2129 	}
2130 	hdr_len = i + 1;
2131 	*prefix_len_out = hdr_len;
2132 	if (val > INT_MAX) {
2133 		// Protobuf messages should always be less than 2 GiB in size.
2134 		// We also want to return early here so that hdr_len + val does
2135 		// not overflow on 32-bit systems.
2136 		PROTOBUF_C_UNPACK_ERROR("length prefix of %lu is too large",
2137 			(unsigned long int)val);
2138 		return 0;
2139 	}
2140 	if (hdr_len + val > len) {
2141 		PROTOBUF_C_UNPACK_ERROR("data too short after length-prefix of %lu",
2142 			(unsigned long int)val);
2143 		return 0;
2144 	}
2145 	return hdr_len + val;
2146 }
2147 
2148 static size_t
max_b128_numbers(size_t len,const uint8_t * data)2149 max_b128_numbers(size_t len, const uint8_t *data)
2150 {
2151 	size_t rv = 0;
2152 	while (len--)
2153 		if ((*data++ & 0x80) == 0)
2154 			++rv;
2155 	return rv;
2156 }
2157 
2158 /**@}*/
2159 
2160 /**
2161  * Merge earlier message into a latter message.
2162  *
2163  * For numeric types and strings, if the same value appears multiple
2164  * times, the parser accepts the last value it sees. For embedded
2165  * message fields, the parser merges multiple instances of the same
2166  * field. That is, all singular scalar fields in the latter instance
2167  * replace those in the former, singular embedded messages are merged,
2168  * and repeated fields are concatenated.
2169  *
2170  * The earlier message should be freed after calling this function, as
2171  * some of its fields may have been reused and changed to their default
2172  * values during the merge.
2173  */
2174 static protobuf_c_boolean
merge_messages(ProtobufCMessage * earlier_msg,ProtobufCMessage * latter_msg,ProtobufCAllocator * allocator)2175 merge_messages(ProtobufCMessage *earlier_msg,
2176 	       ProtobufCMessage *latter_msg,
2177 	       ProtobufCAllocator *allocator)
2178 {
2179 	unsigned i;
2180 	const ProtobufCFieldDescriptor *fields =
2181 		latter_msg->descriptor->fields;
2182 	for (i = 0; i < latter_msg->descriptor->n_fields; i++) {
2183 		if (fields[i].label == PROTOBUF_C_LABEL_REPEATED) {
2184 			size_t *n_earlier =
2185 				STRUCT_MEMBER_PTR(size_t, earlier_msg,
2186 						  fields[i].quantifier_offset);
2187 			uint8_t **p_earlier =
2188 				STRUCT_MEMBER_PTR(uint8_t *, earlier_msg,
2189 						  fields[i].offset);
2190 			size_t *n_latter =
2191 				STRUCT_MEMBER_PTR(size_t, latter_msg,
2192 						  fields[i].quantifier_offset);
2193 			uint8_t **p_latter =
2194 				STRUCT_MEMBER_PTR(uint8_t *, latter_msg,
2195 						  fields[i].offset);
2196 
2197 			if (*n_earlier > 0) {
2198 				if (*n_latter > 0) {
2199 					/* Concatenate the repeated field */
2200 					size_t el_size =
2201 						sizeof_elt_in_repeated_array(fields[i].type);
2202 					uint8_t *new_field;
2203 
2204 					new_field = do_alloc(allocator,
2205 						(*n_earlier + *n_latter) * el_size);
2206 					if (!new_field)
2207 						return FALSE;
2208 
2209 					memcpy(new_field, *p_earlier,
2210 					       *n_earlier * el_size);
2211 					memcpy(new_field +
2212 					       *n_earlier * el_size,
2213 					       *p_latter,
2214 					       *n_latter * el_size);
2215 
2216 					do_free(allocator, *p_latter);
2217 					do_free(allocator, *p_earlier);
2218 					*p_latter = new_field;
2219 					*n_latter = *n_earlier + *n_latter;
2220 				} else {
2221 					/* Zero copy the repeated field from the earlier message */
2222 					*n_latter = *n_earlier;
2223 					*p_latter = *p_earlier;
2224 				}
2225 				/* Make sure the field does not get double freed */
2226 				*n_earlier = 0;
2227 				*p_earlier = 0;
2228 			}
2229 		} else if (fields[i].label == PROTOBUF_C_LABEL_OPTIONAL ||
2230 			   fields[i].label == PROTOBUF_C_LABEL_NONE) {
2231 			const ProtobufCFieldDescriptor *field;
2232 			uint32_t *earlier_case_p = STRUCT_MEMBER_PTR(uint32_t,
2233 								     earlier_msg,
2234 								     fields[i].
2235 								     quantifier_offset);
2236 			uint32_t *latter_case_p = STRUCT_MEMBER_PTR(uint32_t,
2237 								    latter_msg,
2238 								    fields[i].
2239 								    quantifier_offset);
2240 			protobuf_c_boolean need_to_merge = FALSE;
2241 			void *earlier_elem;
2242 			void *latter_elem;
2243 			const void *def_val;
2244 
2245 			if (fields[i].flags & PROTOBUF_C_FIELD_FLAG_ONEOF) {
2246 				if (*latter_case_p == 0) {
2247 					/* lookup correct oneof field */
2248 					int field_index =
2249 						int_range_lookup(
2250 							latter_msg->descriptor
2251 							->n_field_ranges,
2252 							latter_msg->descriptor
2253 							->field_ranges,
2254 							*earlier_case_p);
2255 					if (field_index < 0)
2256 						return FALSE;
2257 					field = latter_msg->descriptor->fields +
2258 						field_index;
2259 				} else {
2260 					/* Oneof is present in the latter message, move on */
2261 					continue;
2262 				}
2263 			} else {
2264 				field = &fields[i];
2265 			}
2266 
2267 			earlier_elem = STRUCT_MEMBER_P(earlier_msg, field->offset);
2268 			latter_elem = STRUCT_MEMBER_P(latter_msg, field->offset);
2269 			def_val = field->default_value;
2270 
2271 			switch (field->type) {
2272 			case PROTOBUF_C_TYPE_MESSAGE: {
2273 				ProtobufCMessage *em = *(ProtobufCMessage **) earlier_elem;
2274 				ProtobufCMessage *lm = *(ProtobufCMessage **) latter_elem;
2275 				if (em != NULL) {
2276 					if (lm != NULL) {
2277 						if (!merge_messages(em, lm, allocator))
2278 							return FALSE;
2279 						/* Already merged */
2280 						need_to_merge = FALSE;
2281 					} else {
2282 						/* Zero copy the message */
2283 						need_to_merge = TRUE;
2284 					}
2285 				}
2286 				break;
2287 			}
2288 			case PROTOBUF_C_TYPE_BYTES: {
2289 				uint8_t *e_data =
2290 					((ProtobufCBinaryData *) earlier_elem)->data;
2291 				uint8_t *l_data =
2292 					((ProtobufCBinaryData *) latter_elem)->data;
2293 				const ProtobufCBinaryData *d_bd =
2294 					(ProtobufCBinaryData *) def_val;
2295 
2296 				need_to_merge =
2297 					(e_data != NULL &&
2298 					 (d_bd == NULL ||
2299 					  e_data != d_bd->data)) &&
2300 					(l_data == NULL ||
2301 					 (d_bd != NULL &&
2302 					  l_data == d_bd->data));
2303 				break;
2304 			}
2305 			case PROTOBUF_C_TYPE_STRING: {
2306 				char *e_str = *(char **) earlier_elem;
2307 				char *l_str = *(char **) latter_elem;
2308 				const char *d_str = def_val;
2309 
2310 				need_to_merge = e_str != d_str && l_str == d_str;
2311 				break;
2312 			}
2313 			default: {
2314 				/* Could be has field or case enum, the logic is
2315 				 * equivalent, since 0 (FALSE) means not set for
2316 				 * oneof */
2317 				need_to_merge = (*earlier_case_p != 0) &&
2318 						(*latter_case_p == 0);
2319 				break;
2320 			}
2321 			}
2322 
2323 			if (need_to_merge) {
2324 				size_t el_size =
2325 					sizeof_elt_in_repeated_array(field->type);
2326 				memcpy(latter_elem, earlier_elem, el_size);
2327 				/*
2328 				 * Reset the element from the old message to 0
2329 				 * to make sure earlier message deallocation
2330 				 * doesn't corrupt zero-copied data in the new
2331 				 * message, earlier message will be freed after
2332 				 * this function is called anyway
2333 				 */
2334 				memset(earlier_elem, 0, el_size);
2335 
2336 				if (field->quantifier_offset != 0) {
2337 					/* Set the has field or the case enum,
2338 					 * if applicable */
2339 					*latter_case_p = *earlier_case_p;
2340 					*earlier_case_p = 0;
2341 				}
2342 			}
2343 		}
2344 	}
2345 	return TRUE;
2346 }
2347 
2348 /**
2349  * Count packed elements.
2350  *
2351  * Given a raw slab of packed-repeated values, determine the number of
2352  * elements. This function detects certain kinds of errors but not
2353  * others; the remaining error checking is done by
2354  * parse_packed_repeated_member().
2355  */
2356 static protobuf_c_boolean
count_packed_elements(ProtobufCType type,size_t len,const uint8_t * data,size_t * count_out)2357 count_packed_elements(ProtobufCType type,
2358 		      size_t len, const uint8_t *data, size_t *count_out)
2359 {
2360 	switch (type) {
2361 	case PROTOBUF_C_TYPE_SFIXED32:
2362 	case PROTOBUF_C_TYPE_FIXED32:
2363 	case PROTOBUF_C_TYPE_FLOAT:
2364 		if (len % 4 != 0) {
2365 			PROTOBUF_C_UNPACK_ERROR("length must be a multiple of 4 for fixed-length 32-bit types");
2366 			return FALSE;
2367 		}
2368 		*count_out = len / 4;
2369 		return TRUE;
2370 	case PROTOBUF_C_TYPE_SFIXED64:
2371 	case PROTOBUF_C_TYPE_FIXED64:
2372 	case PROTOBUF_C_TYPE_DOUBLE:
2373 		if (len % 8 != 0) {
2374 			PROTOBUF_C_UNPACK_ERROR("length must be a multiple of 8 for fixed-length 64-bit types");
2375 			return FALSE;
2376 		}
2377 		*count_out = len / 8;
2378 		return TRUE;
2379 	case PROTOBUF_C_TYPE_ENUM:
2380 	case PROTOBUF_C_TYPE_INT32:
2381 	case PROTOBUF_C_TYPE_SINT32:
2382 	case PROTOBUF_C_TYPE_UINT32:
2383 	case PROTOBUF_C_TYPE_INT64:
2384 	case PROTOBUF_C_TYPE_SINT64:
2385 	case PROTOBUF_C_TYPE_UINT64:
2386 		*count_out = max_b128_numbers(len, data);
2387 		return TRUE;
2388 	case PROTOBUF_C_TYPE_BOOL:
2389 		*count_out = len;
2390 		return TRUE;
2391 	case PROTOBUF_C_TYPE_STRING:
2392 	case PROTOBUF_C_TYPE_BYTES:
2393 	case PROTOBUF_C_TYPE_MESSAGE:
2394 	default:
2395 		PROTOBUF_C_UNPACK_ERROR("bad protobuf-c type %u for packed-repeated", type);
2396 		return FALSE;
2397 	}
2398 }
2399 
2400 static inline uint32_t
parse_uint32(unsigned len,const uint8_t * data)2401 parse_uint32(unsigned len, const uint8_t *data)
2402 {
2403 	uint32_t rv = data[0] & 0x7f;
2404 	if (len > 1) {
2405 		rv |= ((uint32_t) (data[1] & 0x7f) << 7);
2406 		if (len > 2) {
2407 			rv |= ((uint32_t) (data[2] & 0x7f) << 14);
2408 			if (len > 3) {
2409 				rv |= ((uint32_t) (data[3] & 0x7f) << 21);
2410 				if (len > 4)
2411 					rv |= ((uint32_t) (data[4]) << 28);
2412 			}
2413 		}
2414 	}
2415 	return rv;
2416 }
2417 
2418 static inline uint32_t
parse_int32(unsigned len,const uint8_t * data)2419 parse_int32(unsigned len, const uint8_t *data)
2420 {
2421 	return parse_uint32(len, data);
2422 }
2423 
2424 static inline int32_t
unzigzag32(uint32_t v)2425 unzigzag32(uint32_t v)
2426 {
2427 	// Note:  Using unsigned types prevents undefined behavior
2428 	return (int32_t)((v >> 1) ^ (~(v & 1) + 1));
2429 }
2430 
2431 static inline uint32_t
parse_fixed_uint32(const uint8_t * data)2432 parse_fixed_uint32(const uint8_t *data)
2433 {
2434 #if !defined(WORDS_BIGENDIAN)
2435 	uint32_t t;
2436 	memcpy(&t, data, 4);
2437 	return t;
2438 #else
2439 	return data[0] |
2440 		((uint32_t) (data[1]) << 8) |
2441 		((uint32_t) (data[2]) << 16) |
2442 		((uint32_t) (data[3]) << 24);
2443 #endif
2444 }
2445 
2446 static uint64_t
parse_uint64(unsigned len,const uint8_t * data)2447 parse_uint64(unsigned len, const uint8_t *data)
2448 {
2449 	unsigned shift, i;
2450 	uint64_t rv;
2451 
2452 	if (len < 5)
2453 		return parse_uint32(len, data);
2454 	rv = ((uint64_t) (data[0] & 0x7f)) |
2455 		((uint64_t) (data[1] & 0x7f) << 7) |
2456 		((uint64_t) (data[2] & 0x7f) << 14) |
2457 		((uint64_t) (data[3] & 0x7f) << 21);
2458 	shift = 28;
2459 	for (i = 4; i < len; i++) {
2460 		rv |= (((uint64_t) (data[i] & 0x7f)) << shift);
2461 		shift += 7;
2462 	}
2463 	return rv;
2464 }
2465 
2466 static inline int64_t
unzigzag64(uint64_t v)2467 unzigzag64(uint64_t v)
2468 {
2469 	// Note:  Using unsigned types prevents undefined behavior
2470 	return (int64_t)((v >> 1) ^ (~(v & 1) + 1));
2471 }
2472 
2473 static inline uint64_t
parse_fixed_uint64(const uint8_t * data)2474 parse_fixed_uint64(const uint8_t *data)
2475 {
2476 #if !defined(WORDS_BIGENDIAN)
2477 	uint64_t t;
2478 	memcpy(&t, data, 8);
2479 	return t;
2480 #else
2481 	return (uint64_t) parse_fixed_uint32(data) |
2482 		(((uint64_t) parse_fixed_uint32(data + 4)) << 32);
2483 #endif
2484 }
2485 
2486 static protobuf_c_boolean
parse_boolean(unsigned len,const uint8_t * data)2487 parse_boolean(unsigned len, const uint8_t *data)
2488 {
2489 	unsigned i;
2490 	for (i = 0; i < len; i++)
2491 		if (data[i] & 0x7f)
2492 			return TRUE;
2493 	return FALSE;
2494 }
2495 
2496 static protobuf_c_boolean
parse_required_member(ScannedMember * scanned_member,void * member,ProtobufCAllocator * allocator,protobuf_c_boolean maybe_clear)2497 parse_required_member(ScannedMember *scanned_member,
2498 		      void *member,
2499 		      ProtobufCAllocator *allocator,
2500 		      protobuf_c_boolean maybe_clear)
2501 {
2502 	unsigned len = scanned_member->len;
2503 	const uint8_t *data = scanned_member->data;
2504 	uint8_t wire_type = scanned_member->wire_type;
2505 
2506 	switch (scanned_member->field->type) {
2507 	case PROTOBUF_C_TYPE_ENUM:
2508 	case PROTOBUF_C_TYPE_INT32:
2509 		if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT)
2510 			return FALSE;
2511 		*(int32_t *) member = parse_int32(len, data);
2512 		return TRUE;
2513 	case PROTOBUF_C_TYPE_UINT32:
2514 		if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT)
2515 			return FALSE;
2516 		*(uint32_t *) member = parse_uint32(len, data);
2517 		return TRUE;
2518 	case PROTOBUF_C_TYPE_SINT32:
2519 		if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT)
2520 			return FALSE;
2521 		*(int32_t *) member = unzigzag32(parse_uint32(len, data));
2522 		return TRUE;
2523 	case PROTOBUF_C_TYPE_SFIXED32:
2524 	case PROTOBUF_C_TYPE_FIXED32:
2525 	case PROTOBUF_C_TYPE_FLOAT:
2526 		if (wire_type != PROTOBUF_C_WIRE_TYPE_32BIT)
2527 			return FALSE;
2528 		*(uint32_t *) member = parse_fixed_uint32(data);
2529 		return TRUE;
2530 	case PROTOBUF_C_TYPE_INT64:
2531 	case PROTOBUF_C_TYPE_UINT64:
2532 		if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT)
2533 			return FALSE;
2534 		*(uint64_t *) member = parse_uint64(len, data);
2535 		return TRUE;
2536 	case PROTOBUF_C_TYPE_SINT64:
2537 		if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT)
2538 			return FALSE;
2539 		*(int64_t *) member = unzigzag64(parse_uint64(len, data));
2540 		return TRUE;
2541 	case PROTOBUF_C_TYPE_SFIXED64:
2542 	case PROTOBUF_C_TYPE_FIXED64:
2543 	case PROTOBUF_C_TYPE_DOUBLE:
2544 		if (wire_type != PROTOBUF_C_WIRE_TYPE_64BIT)
2545 			return FALSE;
2546 		*(uint64_t *) member = parse_fixed_uint64(data);
2547 		return TRUE;
2548 	case PROTOBUF_C_TYPE_BOOL:
2549 		*(protobuf_c_boolean *) member = parse_boolean(len, data);
2550 		return TRUE;
2551 	case PROTOBUF_C_TYPE_STRING: {
2552 		char **pstr = member;
2553 		unsigned pref_len = scanned_member->length_prefix_len;
2554 
2555 		if (wire_type != PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED)
2556 			return FALSE;
2557 
2558 		if (maybe_clear && *pstr != NULL) {
2559 			const char *def = scanned_member->field->default_value;
2560 			if (*pstr != NULL && *pstr != def)
2561 				do_free(allocator, *pstr);
2562 		}
2563 		*pstr = do_alloc(allocator, len - pref_len + 1);
2564 		if (*pstr == NULL)
2565 			return FALSE;
2566 		memcpy(*pstr, data + pref_len, len - pref_len);
2567 		(*pstr)[len - pref_len] = 0;
2568 		return TRUE;
2569 	}
2570 	case PROTOBUF_C_TYPE_BYTES: {
2571 		ProtobufCBinaryData *bd = member;
2572 		const ProtobufCBinaryData *def_bd;
2573 		unsigned pref_len = scanned_member->length_prefix_len;
2574 
2575 		if (wire_type != PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED)
2576 			return FALSE;
2577 
2578 		def_bd = scanned_member->field->default_value;
2579 		if (maybe_clear &&
2580 		    bd->data != NULL &&
2581 		    (def_bd == NULL || bd->data != def_bd->data))
2582 		{
2583 			do_free(allocator, bd->data);
2584 		}
2585 		if (len > pref_len) {
2586 			bd->data = do_alloc(allocator, len - pref_len);
2587 			if (bd->data == NULL)
2588 				return FALSE;
2589 			memcpy(bd->data, data + pref_len, len - pref_len);
2590 		} else {
2591 			bd->data = NULL;
2592 		}
2593 		bd->len = len - pref_len;
2594 		return TRUE;
2595 	}
2596 	case PROTOBUF_C_TYPE_MESSAGE: {
2597 		ProtobufCMessage **pmessage = member;
2598 		ProtobufCMessage *subm;
2599 		const ProtobufCMessage *def_mess;
2600 		protobuf_c_boolean merge_successful = TRUE;
2601 		unsigned pref_len = scanned_member->length_prefix_len;
2602 
2603 		if (wire_type != PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED)
2604 			return FALSE;
2605 
2606 		def_mess = scanned_member->field->default_value;
2607 		subm = protobuf_c_message_unpack(scanned_member->field->descriptor,
2608 						 allocator,
2609 						 len - pref_len,
2610 						 data + pref_len);
2611 
2612 		if (maybe_clear &&
2613 		    *pmessage != NULL &&
2614 		    *pmessage != def_mess)
2615 		{
2616 			if (subm != NULL)
2617 				merge_successful = merge_messages(*pmessage, subm, allocator);
2618 			/* Delete the previous message */
2619 			protobuf_c_message_free_unpacked(*pmessage, allocator);
2620 		}
2621 		*pmessage = subm;
2622 		if (subm == NULL || !merge_successful)
2623 			return FALSE;
2624 		return TRUE;
2625 	}
2626 	}
2627 	return FALSE;
2628 }
2629 
2630 static protobuf_c_boolean
parse_oneof_member(ScannedMember * scanned_member,void * member,ProtobufCMessage * message,ProtobufCAllocator * allocator)2631 parse_oneof_member (ScannedMember *scanned_member,
2632 		    void *member,
2633 		    ProtobufCMessage *message,
2634 		    ProtobufCAllocator *allocator)
2635 {
2636 	uint32_t *oneof_case = STRUCT_MEMBER_PTR(uint32_t, message,
2637 					       scanned_member->field->quantifier_offset);
2638 
2639 	/* If we have already parsed a member of this oneof, free it. */
2640 	if (*oneof_case != 0) {
2641 		const ProtobufCFieldDescriptor *old_field;
2642 		size_t el_size;
2643 		/* lookup field */
2644 		int field_index =
2645 			int_range_lookup(message->descriptor->n_field_ranges,
2646 					 message->descriptor->field_ranges,
2647 					 *oneof_case);
2648 		if (field_index < 0)
2649 			return FALSE;
2650 		old_field = message->descriptor->fields + field_index;
2651 		el_size = sizeof_elt_in_repeated_array(old_field->type);
2652 
2653 		switch (old_field->type) {
2654 	        case PROTOBUF_C_TYPE_STRING: {
2655 			char **pstr = member;
2656 			const char *def = old_field->default_value;
2657 			if (*pstr != NULL && *pstr != def)
2658 				do_free(allocator, *pstr);
2659 			break;
2660 	        }
2661 		case PROTOBUF_C_TYPE_BYTES: {
2662 			ProtobufCBinaryData *bd = member;
2663 			const ProtobufCBinaryData *def_bd = old_field->default_value;
2664 			if (bd->data != NULL &&
2665 			   (def_bd == NULL || bd->data != def_bd->data))
2666 			{
2667 				do_free(allocator, bd->data);
2668 			}
2669 			break;
2670 	        }
2671 		case PROTOBUF_C_TYPE_MESSAGE: {
2672 			ProtobufCMessage **pmessage = member;
2673 			const ProtobufCMessage *def_mess = old_field->default_value;
2674 			if (*pmessage != NULL && *pmessage != def_mess)
2675 				protobuf_c_message_free_unpacked(*pmessage, allocator);
2676 			break;
2677 	        }
2678 		default:
2679 			break;
2680 		}
2681 
2682 		memset (member, 0, el_size);
2683 	}
2684 	if (!parse_required_member (scanned_member, member, allocator, TRUE))
2685 		return FALSE;
2686 
2687 	*oneof_case = scanned_member->tag;
2688 	return TRUE;
2689 }
2690 
2691 
2692 static protobuf_c_boolean
parse_optional_member(ScannedMember * scanned_member,void * member,ProtobufCMessage * message,ProtobufCAllocator * allocator)2693 parse_optional_member(ScannedMember *scanned_member,
2694 		      void *member,
2695 		      ProtobufCMessage *message,
2696 		      ProtobufCAllocator *allocator)
2697 {
2698 	if (!parse_required_member(scanned_member, member, allocator, TRUE))
2699 		return FALSE;
2700 	if (scanned_member->field->quantifier_offset != 0)
2701 		STRUCT_MEMBER(protobuf_c_boolean,
2702 			      message,
2703 			      scanned_member->field->quantifier_offset) = TRUE;
2704 	return TRUE;
2705 }
2706 
2707 static protobuf_c_boolean
parse_repeated_member(ScannedMember * scanned_member,void * member,ProtobufCMessage * message,ProtobufCAllocator * allocator)2708 parse_repeated_member(ScannedMember *scanned_member,
2709 		      void *member,
2710 		      ProtobufCMessage *message,
2711 		      ProtobufCAllocator *allocator)
2712 {
2713 	const ProtobufCFieldDescriptor *field = scanned_member->field;
2714 	size_t *p_n = STRUCT_MEMBER_PTR(size_t, message, field->quantifier_offset);
2715 	size_t siz = sizeof_elt_in_repeated_array(field->type);
2716 	char *array = *(char **) member;
2717 
2718 	if (!parse_required_member(scanned_member, array + siz * (*p_n),
2719 				   allocator, FALSE))
2720 	{
2721 		return FALSE;
2722 	}
2723 	*p_n += 1;
2724 	return TRUE;
2725 }
2726 
2727 static unsigned
scan_varint(unsigned len,const uint8_t * data)2728 scan_varint(unsigned len, const uint8_t *data)
2729 {
2730 	unsigned i;
2731 	if (len > 10)
2732 		len = 10;
2733 	for (i = 0; i < len; i++)
2734 		if ((data[i] & 0x80) == 0)
2735 			break;
2736 	if (i == len)
2737 		return 0;
2738 	return i + 1;
2739 }
2740 
2741 static protobuf_c_boolean
parse_packed_repeated_member(ScannedMember * scanned_member,void * member,ProtobufCMessage * message)2742 parse_packed_repeated_member(ScannedMember *scanned_member,
2743 			     void *member,
2744 			     ProtobufCMessage *message)
2745 {
2746 	const ProtobufCFieldDescriptor *field = scanned_member->field;
2747 	size_t *p_n = STRUCT_MEMBER_PTR(size_t, message, field->quantifier_offset);
2748 	size_t siz = sizeof_elt_in_repeated_array(field->type);
2749 	void *array = *(char **) member + siz * (*p_n);
2750 	const uint8_t *at = scanned_member->data + scanned_member->length_prefix_len;
2751 	size_t rem = scanned_member->len - scanned_member->length_prefix_len;
2752 	size_t count = 0;
2753 #if defined(WORDS_BIGENDIAN)
2754 	unsigned i;
2755 #endif
2756 
2757 	switch (field->type) {
2758 	case PROTOBUF_C_TYPE_SFIXED32:
2759 	case PROTOBUF_C_TYPE_FIXED32:
2760 	case PROTOBUF_C_TYPE_FLOAT:
2761 		count = (scanned_member->len - scanned_member->length_prefix_len) / 4;
2762 #if !defined(WORDS_BIGENDIAN)
2763 		goto no_unpacking_needed;
2764 #else
2765 		for (i = 0; i < count; i++) {
2766 			((uint32_t *) array)[i] = parse_fixed_uint32(at);
2767 			at += 4;
2768 		}
2769 		break;
2770 #endif
2771 	case PROTOBUF_C_TYPE_SFIXED64:
2772 	case PROTOBUF_C_TYPE_FIXED64:
2773 	case PROTOBUF_C_TYPE_DOUBLE:
2774 		count = (scanned_member->len - scanned_member->length_prefix_len) / 8;
2775 #if !defined(WORDS_BIGENDIAN)
2776 		goto no_unpacking_needed;
2777 #else
2778 		for (i = 0; i < count; i++) {
2779 			((uint64_t *) array)[i] = parse_fixed_uint64(at);
2780 			at += 8;
2781 		}
2782 		break;
2783 #endif
2784 	case PROTOBUF_C_TYPE_ENUM:
2785 	case PROTOBUF_C_TYPE_INT32:
2786 		while (rem > 0) {
2787 			unsigned s = scan_varint(rem, at);
2788 			if (s == 0) {
2789 				PROTOBUF_C_UNPACK_ERROR("bad packed-repeated int32 value");
2790 				return FALSE;
2791 			}
2792 			((int32_t *) array)[count++] = parse_int32(s, at);
2793 			at += s;
2794 			rem -= s;
2795 		}
2796 		break;
2797 	case PROTOBUF_C_TYPE_SINT32:
2798 		while (rem > 0) {
2799 			unsigned s = scan_varint(rem, at);
2800 			if (s == 0) {
2801 				PROTOBUF_C_UNPACK_ERROR("bad packed-repeated sint32 value");
2802 				return FALSE;
2803 			}
2804 			((int32_t *) array)[count++] = unzigzag32(parse_uint32(s, at));
2805 			at += s;
2806 			rem -= s;
2807 		}
2808 		break;
2809 	case PROTOBUF_C_TYPE_UINT32:
2810 		while (rem > 0) {
2811 			unsigned s = scan_varint(rem, at);
2812 			if (s == 0) {
2813 				PROTOBUF_C_UNPACK_ERROR("bad packed-repeated enum or uint32 value");
2814 				return FALSE;
2815 			}
2816 			((uint32_t *) array)[count++] = parse_uint32(s, at);
2817 			at += s;
2818 			rem -= s;
2819 		}
2820 		break;
2821 
2822 	case PROTOBUF_C_TYPE_SINT64:
2823 		while (rem > 0) {
2824 			unsigned s = scan_varint(rem, at);
2825 			if (s == 0) {
2826 				PROTOBUF_C_UNPACK_ERROR("bad packed-repeated sint64 value");
2827 				return FALSE;
2828 			}
2829 			((int64_t *) array)[count++] = unzigzag64(parse_uint64(s, at));
2830 			at += s;
2831 			rem -= s;
2832 		}
2833 		break;
2834 	case PROTOBUF_C_TYPE_INT64:
2835 	case PROTOBUF_C_TYPE_UINT64:
2836 		while (rem > 0) {
2837 			unsigned s = scan_varint(rem, at);
2838 			if (s == 0) {
2839 				PROTOBUF_C_UNPACK_ERROR("bad packed-repeated int64/uint64 value");
2840 				return FALSE;
2841 			}
2842 			((int64_t *) array)[count++] = parse_uint64(s, at);
2843 			at += s;
2844 			rem -= s;
2845 		}
2846 		break;
2847 	case PROTOBUF_C_TYPE_BOOL:
2848 		while (rem > 0) {
2849 			unsigned s = scan_varint(rem, at);
2850 			if (s == 0) {
2851 				PROTOBUF_C_UNPACK_ERROR("bad packed-repeated boolean value");
2852 				return FALSE;
2853 			}
2854 			((protobuf_c_boolean *) array)[count++] = parse_boolean(s, at);
2855 			at += s;
2856 			rem -= s;
2857 		}
2858 		break;
2859 	default:
2860 		PROTOBUF_C__ASSERT_NOT_REACHED();
2861 	}
2862 	*p_n += count;
2863 	return TRUE;
2864 
2865 #if !defined(WORDS_BIGENDIAN)
2866 no_unpacking_needed:
2867 	memcpy(array, at, count * siz);
2868 	*p_n += count;
2869 	return TRUE;
2870 #endif
2871 }
2872 
2873 static protobuf_c_boolean
is_packable_type(ProtobufCType type)2874 is_packable_type(ProtobufCType type)
2875 {
2876 	return
2877 		type != PROTOBUF_C_TYPE_STRING &&
2878 		type != PROTOBUF_C_TYPE_BYTES &&
2879 		type != PROTOBUF_C_TYPE_MESSAGE;
2880 }
2881 
2882 static protobuf_c_boolean
parse_member(ScannedMember * scanned_member,ProtobufCMessage * message,ProtobufCAllocator * allocator)2883 parse_member(ScannedMember *scanned_member,
2884 	     ProtobufCMessage *message,
2885 	     ProtobufCAllocator *allocator)
2886 {
2887 	const ProtobufCFieldDescriptor *field = scanned_member->field;
2888 	void *member;
2889 
2890 	if (field == NULL) {
2891 		ProtobufCMessageUnknownField *ufield =
2892 			message->unknown_fields +
2893 			(message->n_unknown_fields++);
2894 		ufield->tag = scanned_member->tag;
2895 		ufield->wire_type = scanned_member->wire_type;
2896 		ufield->len = scanned_member->len;
2897 		ufield->data = do_alloc(allocator, scanned_member->len);
2898 		if (ufield->data == NULL)
2899 			return FALSE;
2900 		memcpy(ufield->data, scanned_member->data, ufield->len);
2901 		return TRUE;
2902 	}
2903 	member = (char *) message + field->offset;
2904 	switch (field->label) {
2905 	case PROTOBUF_C_LABEL_REQUIRED:
2906 		return parse_required_member(scanned_member, member,
2907 					     allocator, TRUE);
2908 	case PROTOBUF_C_LABEL_OPTIONAL:
2909 	case PROTOBUF_C_LABEL_NONE:
2910 		if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF)) {
2911 			return parse_oneof_member(scanned_member, member,
2912 						  message, allocator);
2913 		} else {
2914 			return parse_optional_member(scanned_member, member,
2915 						     message, allocator);
2916 		}
2917 	case PROTOBUF_C_LABEL_REPEATED:
2918 		if (scanned_member->wire_type ==
2919 		    PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED &&
2920 		    (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED) ||
2921 		     is_packable_type(field->type)))
2922 		{
2923 			return parse_packed_repeated_member(scanned_member,
2924 							    member, message);
2925 		} else {
2926 			return parse_repeated_member(scanned_member,
2927 						     member, message,
2928 						     allocator);
2929 		}
2930 	}
2931 	PROTOBUF_C__ASSERT_NOT_REACHED();
2932 	return 0;
2933 }
2934 
2935 /**
2936  * Initialise messages generated by old code.
2937  *
2938  * This function is used if desc->message_init == NULL (which occurs
2939  * for old code, and which would be useful to support allocating
2940  * descriptors dynamically).
2941  */
2942 static void
message_init_generic(const ProtobufCMessageDescriptor * desc,ProtobufCMessage * message)2943 message_init_generic(const ProtobufCMessageDescriptor *desc,
2944 		     ProtobufCMessage *message)
2945 {
2946 	unsigned i;
2947 
2948 	memset(message, 0, desc->sizeof_message);
2949 	message->descriptor = desc;
2950 	for (i = 0; i < desc->n_fields; i++) {
2951 		if (desc->fields[i].default_value != NULL &&
2952 		    desc->fields[i].label != PROTOBUF_C_LABEL_REPEATED)
2953 		{
2954 			void *field =
2955 				STRUCT_MEMBER_P(message, desc->fields[i].offset);
2956 			const void *dv = desc->fields[i].default_value;
2957 
2958 			switch (desc->fields[i].type) {
2959 			case PROTOBUF_C_TYPE_INT32:
2960 			case PROTOBUF_C_TYPE_SINT32:
2961 			case PROTOBUF_C_TYPE_SFIXED32:
2962 			case PROTOBUF_C_TYPE_UINT32:
2963 			case PROTOBUF_C_TYPE_FIXED32:
2964 			case PROTOBUF_C_TYPE_FLOAT:
2965 			case PROTOBUF_C_TYPE_ENUM:
2966 				memcpy(field, dv, 4);
2967 				break;
2968 			case PROTOBUF_C_TYPE_INT64:
2969 			case PROTOBUF_C_TYPE_SINT64:
2970 			case PROTOBUF_C_TYPE_SFIXED64:
2971 			case PROTOBUF_C_TYPE_UINT64:
2972 			case PROTOBUF_C_TYPE_FIXED64:
2973 			case PROTOBUF_C_TYPE_DOUBLE:
2974 				memcpy(field, dv, 8);
2975 				break;
2976 			case PROTOBUF_C_TYPE_BOOL:
2977 				memcpy(field, dv, sizeof(protobuf_c_boolean));
2978 				break;
2979 			case PROTOBUF_C_TYPE_BYTES:
2980 				memcpy(field, dv, sizeof(ProtobufCBinaryData));
2981 				break;
2982 
2983 			case PROTOBUF_C_TYPE_STRING:
2984 			case PROTOBUF_C_TYPE_MESSAGE:
2985 				/*
2986 				 * The next line essentially implements a cast
2987 				 * from const, which is totally unavoidable.
2988 				 */
2989 				*(const void **) field = dv;
2990 				break;
2991 			}
2992 		}
2993 	}
2994 }
2995 
2996 /**@}*/
2997 
2998 /*
2999  * ScannedMember slabs (an unpacking implementation detail). Before doing real
3000  * unpacking, we first scan through the elements to see how many there are (for
3001  * repeated fields), and which field to use (for non-repeated fields given
3002  * twice).
3003  *
3004  * In order to avoid allocations for small messages, we keep a stack-allocated
3005  * slab of ScannedMembers of size FIRST_SCANNED_MEMBER_SLAB_SIZE (16). After we
3006  * fill that up, we allocate each slab twice as large as the previous one.
3007  */
3008 #define FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2 4
3009 
3010 /*
3011  * The number of slabs, including the stack-allocated ones; choose the number so
3012  * that we would overflow if we needed a slab larger than provided.
3013  */
3014 #define MAX_SCANNED_MEMBER_SLAB			\
3015   (sizeof(unsigned int)*8 - 1			\
3016    - BOUND_SIZEOF_SCANNED_MEMBER_LOG2		\
3017    - FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2)
3018 
3019 #define REQUIRED_FIELD_BITMAP_SET(index)	\
3020 	(required_fields_bitmap[(index)/8] |= (1UL<<((index)%8)))
3021 
3022 #define REQUIRED_FIELD_BITMAP_IS_SET(index)	\
3023 	(required_fields_bitmap[(index)/8] & (1UL<<((index)%8)))
3024 
3025 ProtobufCMessage *
protobuf_c_message_unpack(const ProtobufCMessageDescriptor * desc,ProtobufCAllocator * allocator,size_t len,const uint8_t * data)3026 protobuf_c_message_unpack(const ProtobufCMessageDescriptor *desc,
3027 			  ProtobufCAllocator *allocator,
3028 			  size_t len, const uint8_t *data)
3029 {
3030 	ProtobufCMessage *rv;
3031 	size_t rem = len;
3032 	const uint8_t *at = data;
3033 	const ProtobufCFieldDescriptor *last_field = desc->fields + 0;
3034 	ScannedMember first_member_slab[1UL <<
3035 					FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2];
3036 
3037 	/*
3038 	 * scanned_member_slabs[i] is an array of arrays of ScannedMember.
3039 	 * The first slab (scanned_member_slabs[0] is just a pointer to
3040 	 * first_member_slab), above. All subsequent slabs will be allocated
3041 	 * using the allocator.
3042 	 */
3043 	ScannedMember *scanned_member_slabs[MAX_SCANNED_MEMBER_SLAB + 1];
3044 	unsigned which_slab = 0; /* the slab we are currently populating */
3045 	unsigned in_slab_index = 0; /* number of members in the slab */
3046 	size_t n_unknown = 0;
3047 	unsigned f;
3048 	unsigned j;
3049 	unsigned i_slab;
3050 	unsigned last_field_index = 0;
3051 	unsigned required_fields_bitmap_len;
3052 	unsigned char required_fields_bitmap_stack[16];
3053 	unsigned char *required_fields_bitmap = required_fields_bitmap_stack;
3054 	protobuf_c_boolean required_fields_bitmap_alloced = FALSE;
3055 
3056 	ASSERT_IS_MESSAGE_DESCRIPTOR(desc);
3057 
3058 	if (allocator == NULL)
3059 		allocator = &protobuf_c__allocator;
3060 
3061 	rv = do_alloc(allocator, desc->sizeof_message);
3062 	if (!rv)
3063 		return (NULL);
3064 	scanned_member_slabs[0] = first_member_slab;
3065 
3066 	required_fields_bitmap_len = (desc->n_fields + 7) / 8;
3067 	if (required_fields_bitmap_len > sizeof(required_fields_bitmap_stack)) {
3068 		required_fields_bitmap = do_alloc(allocator, required_fields_bitmap_len);
3069 		if (!required_fields_bitmap) {
3070 			do_free(allocator, rv);
3071 			return (NULL);
3072 		}
3073 		required_fields_bitmap_alloced = TRUE;
3074 	}
3075 	memset(required_fields_bitmap, 0, required_fields_bitmap_len);
3076 
3077 	/*
3078 	 * Generated code always defines "message_init". However, we provide a
3079 	 * fallback for (1) users of old protobuf-c generated-code that do not
3080 	 * provide the function, and (2) descriptors constructed from some other
3081 	 * source (most likely, direct construction from the .proto file).
3082 	 */
3083 	if (desc->message_init != NULL)
3084 		protobuf_c_message_init(desc, rv);
3085 	else
3086 		message_init_generic(desc, rv);
3087 
3088 	while (rem > 0) {
3089 		uint32_t tag;
3090 		uint8_t wire_type;
3091 		size_t used = parse_tag_and_wiretype(rem, at, &tag, &wire_type);
3092 		const ProtobufCFieldDescriptor *field;
3093 		ScannedMember tmp;
3094 
3095 		if (used == 0) {
3096 			PROTOBUF_C_UNPACK_ERROR("error parsing tag/wiretype at offset %u",
3097 						(unsigned) (at - data));
3098 			goto error_cleanup_during_scan;
3099 		}
3100 		/*
3101 		 * \todo Consider optimizing for field[1].id == tag, if field[1]
3102 		 * exists!
3103 		 */
3104 		if (last_field == NULL || last_field->id != tag) {
3105 			/* lookup field */
3106 			int field_index =
3107 			    int_range_lookup(desc->n_field_ranges,
3108 					     desc->field_ranges,
3109 					     tag);
3110 			if (field_index < 0) {
3111 				field = NULL;
3112 				n_unknown++;
3113 			} else {
3114 				field = desc->fields + field_index;
3115 				last_field = field;
3116 				last_field_index = field_index;
3117 			}
3118 		} else {
3119 			field = last_field;
3120 		}
3121 
3122 		if (field != NULL && field->label == PROTOBUF_C_LABEL_REQUIRED)
3123 			REQUIRED_FIELD_BITMAP_SET(last_field_index);
3124 
3125 		at += used;
3126 		rem -= used;
3127 		tmp.tag = tag;
3128 		tmp.wire_type = wire_type;
3129 		tmp.field = field;
3130 		tmp.data = at;
3131 		tmp.length_prefix_len = 0;
3132 
3133 		switch (wire_type) {
3134 		case PROTOBUF_C_WIRE_TYPE_VARINT: {
3135 			unsigned max_len = rem < 10 ? rem : 10;
3136 			unsigned i;
3137 
3138 			for (i = 0; i < max_len; i++)
3139 				if ((at[i] & 0x80) == 0)
3140 					break;
3141 			if (i == max_len) {
3142 				PROTOBUF_C_UNPACK_ERROR("unterminated varint at offset %u",
3143 							(unsigned) (at - data));
3144 				goto error_cleanup_during_scan;
3145 			}
3146 			tmp.len = i + 1;
3147 			break;
3148 		}
3149 		case PROTOBUF_C_WIRE_TYPE_64BIT:
3150 			if (rem < 8) {
3151 				PROTOBUF_C_UNPACK_ERROR("too short after 64bit wiretype at offset %u",
3152 							(unsigned) (at - data));
3153 				goto error_cleanup_during_scan;
3154 			}
3155 			tmp.len = 8;
3156 			break;
3157 		case PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED: {
3158 			size_t pref_len;
3159 
3160 			tmp.len = scan_length_prefixed_data(rem, at, &pref_len);
3161 			if (tmp.len == 0) {
3162 				/* NOTE: scan_length_prefixed_data calls UNPACK_ERROR */
3163 				goto error_cleanup_during_scan;
3164 			}
3165 			tmp.length_prefix_len = pref_len;
3166 			break;
3167 		}
3168 		case PROTOBUF_C_WIRE_TYPE_32BIT:
3169 			if (rem < 4) {
3170 				PROTOBUF_C_UNPACK_ERROR("too short after 32bit wiretype at offset %u",
3171 					      (unsigned) (at - data));
3172 				goto error_cleanup_during_scan;
3173 			}
3174 			tmp.len = 4;
3175 			break;
3176 		default:
3177 			PROTOBUF_C_UNPACK_ERROR("unsupported tag %u at offset %u",
3178 						wire_type, (unsigned) (at - data));
3179 			goto error_cleanup_during_scan;
3180 		}
3181 
3182 		if (in_slab_index == (1UL <<
3183 			(which_slab + FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2)))
3184 		{
3185 			size_t size;
3186 
3187 			in_slab_index = 0;
3188 			if (which_slab == MAX_SCANNED_MEMBER_SLAB) {
3189 				PROTOBUF_C_UNPACK_ERROR("too many fields");
3190 				goto error_cleanup_during_scan;
3191 			}
3192 			which_slab++;
3193 			size = sizeof(ScannedMember)
3194 				<< (which_slab + FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2);
3195 			scanned_member_slabs[which_slab] = do_alloc(allocator, size);
3196 			if (scanned_member_slabs[which_slab] == NULL)
3197 				goto error_cleanup_during_scan;
3198 		}
3199 		scanned_member_slabs[which_slab][in_slab_index++] = tmp;
3200 
3201 		if (field != NULL && field->label == PROTOBUF_C_LABEL_REPEATED) {
3202 			size_t *n = STRUCT_MEMBER_PTR(size_t, rv,
3203 						      field->quantifier_offset);
3204 			if (wire_type == PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED &&
3205 			    (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED) ||
3206 			     is_packable_type(field->type)))
3207 			{
3208 				size_t count;
3209 				if (!count_packed_elements(field->type,
3210 							   tmp.len -
3211 							   tmp.length_prefix_len,
3212 							   tmp.data +
3213 							   tmp.length_prefix_len,
3214 							   &count))
3215 				{
3216 					PROTOBUF_C_UNPACK_ERROR("counting packed elements");
3217 					goto error_cleanup_during_scan;
3218 				}
3219 				*n += count;
3220 			} else {
3221 				*n += 1;
3222 			}
3223 		}
3224 
3225 		at += tmp.len;
3226 		rem -= tmp.len;
3227 	}
3228 
3229 	/* allocate space for repeated fields, also check that all required fields have been set */
3230 	for (f = 0; f < desc->n_fields; f++) {
3231 		const ProtobufCFieldDescriptor *field = desc->fields + f;
3232 		if (field->label == PROTOBUF_C_LABEL_REPEATED) {
3233 			size_t siz =
3234 			    sizeof_elt_in_repeated_array(field->type);
3235 			size_t *n_ptr =
3236 			    STRUCT_MEMBER_PTR(size_t, rv,
3237 					      field->quantifier_offset);
3238 			if (*n_ptr != 0) {
3239 				unsigned n = *n_ptr;
3240 				void *a;
3241 				*n_ptr = 0;
3242 				assert(rv->descriptor != NULL);
3243 #define CLEAR_REMAINING_N_PTRS()                                              \
3244               for(f++;f < desc->n_fields; f++)                                \
3245                 {                                                             \
3246                   field = desc->fields + f;                                   \
3247                   if (field->label == PROTOBUF_C_LABEL_REPEATED)              \
3248                     STRUCT_MEMBER (size_t, rv, field->quantifier_offset) = 0; \
3249                 }
3250 				a = do_alloc(allocator, siz * n);
3251 				if (!a) {
3252 					CLEAR_REMAINING_N_PTRS();
3253 					goto error_cleanup;
3254 				}
3255 				STRUCT_MEMBER(void *, rv, field->offset) = a;
3256 			}
3257 		} else if (field->label == PROTOBUF_C_LABEL_REQUIRED) {
3258 			if (field->default_value == NULL &&
3259 			    !REQUIRED_FIELD_BITMAP_IS_SET(f))
3260 			{
3261 				CLEAR_REMAINING_N_PTRS();
3262 				PROTOBUF_C_UNPACK_ERROR("message '%s': missing required field '%s'",
3263 							desc->name, field->name);
3264 				goto error_cleanup;
3265 			}
3266 		}
3267 	}
3268 #undef CLEAR_REMAINING_N_PTRS
3269 
3270 	/* allocate space for unknown fields */
3271 	if (n_unknown) {
3272 		rv->unknown_fields = do_alloc(allocator,
3273 					      n_unknown * sizeof(ProtobufCMessageUnknownField));
3274 		if (rv->unknown_fields == NULL)
3275 			goto error_cleanup;
3276 	}
3277 
3278 	/* do real parsing */
3279 	for (i_slab = 0; i_slab <= which_slab; i_slab++) {
3280 		unsigned max = (i_slab == which_slab) ?
3281 			in_slab_index : (1UL << (i_slab + 4));
3282 		ScannedMember *slab = scanned_member_slabs[i_slab];
3283 
3284 		for (j = 0; j < max; j++) {
3285 			if (!parse_member(slab + j, rv, allocator)) {
3286 				PROTOBUF_C_UNPACK_ERROR("error parsing member %s of %s",
3287 							slab->field ? slab->field->name : "*unknown-field*",
3288 					desc->name);
3289 				goto error_cleanup;
3290 			}
3291 		}
3292 	}
3293 
3294 	/* cleanup */
3295 	for (j = 1; j <= which_slab; j++)
3296 		do_free(allocator, scanned_member_slabs[j]);
3297 	if (required_fields_bitmap_alloced)
3298 		do_free(allocator, required_fields_bitmap);
3299 	return rv;
3300 
3301 error_cleanup:
3302 	protobuf_c_message_free_unpacked(rv, allocator);
3303 	for (j = 1; j <= which_slab; j++)
3304 		do_free(allocator, scanned_member_slabs[j]);
3305 	if (required_fields_bitmap_alloced)
3306 		do_free(allocator, required_fields_bitmap);
3307 	return NULL;
3308 
3309 error_cleanup_during_scan:
3310 	do_free(allocator, rv);
3311 	for (j = 1; j <= which_slab; j++)
3312 		do_free(allocator, scanned_member_slabs[j]);
3313 	if (required_fields_bitmap_alloced)
3314 		do_free(allocator, required_fields_bitmap);
3315 	return NULL;
3316 }
3317 
3318 void
protobuf_c_message_free_unpacked(ProtobufCMessage * message,ProtobufCAllocator * allocator)3319 protobuf_c_message_free_unpacked(ProtobufCMessage *message,
3320 				 ProtobufCAllocator *allocator)
3321 {
3322 	const ProtobufCMessageDescriptor *desc;
3323 	unsigned f;
3324 
3325 	if (message == NULL)
3326 		return;
3327 
3328 	desc = message->descriptor;
3329 
3330 	ASSERT_IS_MESSAGE(message);
3331 
3332 	if (allocator == NULL)
3333 		allocator = &protobuf_c__allocator;
3334 	message->descriptor = NULL;
3335 	for (f = 0; f < desc->n_fields; f++) {
3336 		if (0 != (desc->fields[f].flags & PROTOBUF_C_FIELD_FLAG_ONEOF) &&
3337 		    desc->fields[f].id !=
3338 		    STRUCT_MEMBER(uint32_t, message, desc->fields[f].quantifier_offset))
3339 		{
3340 			/* This is not the selected oneof, skip it */
3341 			continue;
3342 		}
3343 
3344 		if (desc->fields[f].label == PROTOBUF_C_LABEL_REPEATED) {
3345 			size_t n = STRUCT_MEMBER(size_t,
3346 						 message,
3347 						 desc->fields[f].quantifier_offset);
3348 			void *arr = STRUCT_MEMBER(void *,
3349 						  message,
3350 						  desc->fields[f].offset);
3351 
3352 			if (arr != NULL) {
3353 				if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) {
3354 					unsigned i;
3355 					for (i = 0; i < n; i++)
3356 						do_free(allocator, ((char **) arr)[i]);
3357 				} else if (desc->fields[f].type == PROTOBUF_C_TYPE_BYTES) {
3358 					unsigned i;
3359 					for (i = 0; i < n; i++)
3360 						do_free(allocator, ((ProtobufCBinaryData *) arr)[i].data);
3361 				} else if (desc->fields[f].type == PROTOBUF_C_TYPE_MESSAGE) {
3362 					unsigned i;
3363 					for (i = 0; i < n; i++)
3364 						protobuf_c_message_free_unpacked(
3365 							((ProtobufCMessage **) arr)[i],
3366 							allocator
3367 						);
3368 				}
3369 				do_free(allocator, arr);
3370 			}
3371 		} else if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) {
3372 			char *str = STRUCT_MEMBER(char *, message,
3373 						  desc->fields[f].offset);
3374 
3375 			if (str && str != desc->fields[f].default_value)
3376 				do_free(allocator, str);
3377 		} else if (desc->fields[f].type == PROTOBUF_C_TYPE_BYTES) {
3378 			void *data = STRUCT_MEMBER(ProtobufCBinaryData, message,
3379 						   desc->fields[f].offset).data;
3380 			const ProtobufCBinaryData *default_bd;
3381 
3382 			default_bd = desc->fields[f].default_value;
3383 			if (data != NULL &&
3384 			    (default_bd == NULL ||
3385 			     default_bd->data != data))
3386 			{
3387 				do_free(allocator, data);
3388 			}
3389 		} else if (desc->fields[f].type == PROTOBUF_C_TYPE_MESSAGE) {
3390 			ProtobufCMessage *sm;
3391 
3392 			sm = STRUCT_MEMBER(ProtobufCMessage *, message,
3393 					   desc->fields[f].offset);
3394 			if (sm && sm != desc->fields[f].default_value)
3395 				protobuf_c_message_free_unpacked(sm, allocator);
3396 		}
3397 	}
3398 
3399 	for (f = 0; f < message->n_unknown_fields; f++)
3400 		do_free(allocator, message->unknown_fields[f].data);
3401 	if (message->unknown_fields != NULL)
3402 		do_free(allocator, message->unknown_fields);
3403 
3404 	do_free(allocator, message);
3405 }
3406 
3407 void
protobuf_c_message_init(const ProtobufCMessageDescriptor * descriptor,void * message)3408 protobuf_c_message_init(const ProtobufCMessageDescriptor * descriptor,
3409 			void *message)
3410 {
3411 	descriptor->message_init((ProtobufCMessage *) (message));
3412 }
3413 
3414 protobuf_c_boolean
protobuf_c_message_check(const ProtobufCMessage * message)3415 protobuf_c_message_check(const ProtobufCMessage *message)
3416 {
3417 	unsigned i;
3418 
3419 	if (!message ||
3420 	    !message->descriptor ||
3421 	    message->descriptor->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC)
3422 	{
3423 		return FALSE;
3424 	}
3425 
3426 	for (i = 0; i < message->descriptor->n_fields; i++) {
3427 		const ProtobufCFieldDescriptor *f = message->descriptor->fields + i;
3428 		ProtobufCType type = f->type;
3429 		ProtobufCLabel label = f->label;
3430 		void *field = STRUCT_MEMBER_P (message, f->offset);
3431 
3432 		if (f->flags & PROTOBUF_C_FIELD_FLAG_ONEOF) {
3433 			const uint32_t *oneof_case = STRUCT_MEMBER_P (message, f->quantifier_offset);
3434 			if (f->id != *oneof_case) {
3435 				continue; //Do not check if it is an unpopulated oneof member.
3436 			}
3437 		}
3438 
3439 		if (label == PROTOBUF_C_LABEL_REPEATED) {
3440 			size_t *quantity = STRUCT_MEMBER_P (message, f->quantifier_offset);
3441 
3442 			if (*quantity > 0 && *(void **) field == NULL) {
3443 				return FALSE;
3444 			}
3445 
3446 			if (type == PROTOBUF_C_TYPE_MESSAGE) {
3447 				ProtobufCMessage **submessage = *(ProtobufCMessage ***) field;
3448 				unsigned j;
3449 				for (j = 0; j < *quantity; j++) {
3450 					if (!protobuf_c_message_check(submessage[j]))
3451 						return FALSE;
3452 				}
3453 			} else if (type == PROTOBUF_C_TYPE_STRING) {
3454 				char **string = *(char ***) field;
3455 				unsigned j;
3456 				for (j = 0; j < *quantity; j++) {
3457 					if (!string[j])
3458 						return FALSE;
3459 				}
3460 			} else if (type == PROTOBUF_C_TYPE_BYTES) {
3461 				ProtobufCBinaryData *bd = *(ProtobufCBinaryData **) field;
3462 				unsigned j;
3463 				for (j = 0; j < *quantity; j++) {
3464 					if (bd[j].len > 0 && bd[j].data == NULL)
3465 						return FALSE;
3466 				}
3467 			}
3468 
3469 		} else { /* PROTOBUF_C_LABEL_REQUIRED or PROTOBUF_C_LABEL_OPTIONAL */
3470 
3471 			if (type == PROTOBUF_C_TYPE_MESSAGE) {
3472 				ProtobufCMessage *submessage = *(ProtobufCMessage **) field;
3473 				if (label == PROTOBUF_C_LABEL_REQUIRED || submessage != NULL) {
3474 					if (!protobuf_c_message_check(submessage))
3475 						return FALSE;
3476 				}
3477 			} else if (type == PROTOBUF_C_TYPE_STRING) {
3478 				char *string = *(char **) field;
3479 				if (label == PROTOBUF_C_LABEL_REQUIRED && string == NULL)
3480 					return FALSE;
3481 			} else if (type == PROTOBUF_C_TYPE_BYTES) {
3482 				protobuf_c_boolean *has = STRUCT_MEMBER_P (message, f->quantifier_offset);
3483 				ProtobufCBinaryData *bd = field;
3484 				if (label == PROTOBUF_C_LABEL_REQUIRED || *has == TRUE) {
3485 					if (bd->len > 0 && bd->data == NULL)
3486 						return FALSE;
3487 				}
3488 			}
3489 		}
3490 	}
3491 
3492 	return TRUE;
3493 }
3494 
3495 /* === services === */
3496 
3497 typedef void (*GenericHandler) (void *service,
3498 				const ProtobufCMessage *input,
3499 				ProtobufCClosure closure,
3500 				void *closure_data);
3501 void
protobuf_c_service_invoke_internal(ProtobufCService * service,unsigned method_index,const ProtobufCMessage * input,ProtobufCClosure closure,void * closure_data)3502 protobuf_c_service_invoke_internal(ProtobufCService *service,
3503 				   unsigned method_index,
3504 				   const ProtobufCMessage *input,
3505 				   ProtobufCClosure closure,
3506 				   void *closure_data)
3507 {
3508 	GenericHandler *handlers;
3509 	GenericHandler handler;
3510 
3511 	/*
3512 	 * Verify that method_index is within range. If this fails, you are
3513 	 * likely invoking a newly added method on an old service. (Although
3514 	 * other memory corruption bugs can cause this assertion too.)
3515 	 */
3516 	assert(method_index < service->descriptor->n_methods);
3517 
3518 	/*
3519 	 * Get the array of virtual methods (which are enumerated by the
3520 	 * generated code).
3521 	 */
3522 	handlers = (GenericHandler *) (service + 1);
3523 
3524 	/*
3525 	 * Get our method and invoke it.
3526 	 * \todo Seems like handler == NULL is a situation that needs handling.
3527 	 */
3528 	handler = handlers[method_index];
3529 	(*handler)(service, input, closure, closure_data);
3530 }
3531 
3532 void
protobuf_c_service_generated_init(ProtobufCService * service,const ProtobufCServiceDescriptor * descriptor,ProtobufCServiceDestroy destroy)3533 protobuf_c_service_generated_init(ProtobufCService *service,
3534 				  const ProtobufCServiceDescriptor *descriptor,
3535 				  ProtobufCServiceDestroy destroy)
3536 {
3537 	ASSERT_IS_SERVICE_DESCRIPTOR(descriptor);
3538 	service->descriptor = descriptor;
3539 	service->destroy = destroy;
3540 	service->invoke = protobuf_c_service_invoke_internal;
3541 	memset(service + 1, 0, descriptor->n_methods * sizeof(GenericHandler));
3542 }
3543 
protobuf_c_service_destroy(ProtobufCService * service)3544 void protobuf_c_service_destroy(ProtobufCService *service)
3545 {
3546 	service->destroy(service);
3547 }
3548 
3549 /* --- querying the descriptors --- */
3550 
3551 const ProtobufCEnumValue *
protobuf_c_enum_descriptor_get_value_by_name(const ProtobufCEnumDescriptor * desc,const char * name)3552 protobuf_c_enum_descriptor_get_value_by_name(const ProtobufCEnumDescriptor *desc,
3553 					     const char *name)
3554 {
3555 	unsigned start = 0;
3556 	unsigned count;
3557 
3558 	if (desc == NULL || desc->values_by_name == NULL)
3559 		return NULL;
3560 
3561 	count = desc->n_value_names;
3562 
3563 	while (count > 1) {
3564 		unsigned mid = start + count / 2;
3565 		int rv = strcmp(desc->values_by_name[mid].name, name);
3566 		if (rv == 0)
3567 			return desc->values + desc->values_by_name[mid].index;
3568 		else if (rv < 0) {
3569 			count = start + count - (mid + 1);
3570 			start = mid + 1;
3571 		} else
3572 			count = mid - start;
3573 	}
3574 	if (count == 0)
3575 		return NULL;
3576 	if (strcmp(desc->values_by_name[start].name, name) == 0)
3577 		return desc->values + desc->values_by_name[start].index;
3578 	return NULL;
3579 }
3580 
3581 const ProtobufCEnumValue *
protobuf_c_enum_descriptor_get_value(const ProtobufCEnumDescriptor * desc,int value)3582 protobuf_c_enum_descriptor_get_value(const ProtobufCEnumDescriptor *desc,
3583 				     int value)
3584 {
3585 	int rv = int_range_lookup(desc->n_value_ranges, desc->value_ranges, value);
3586 	if (rv < 0)
3587 		return NULL;
3588 	return desc->values + rv;
3589 }
3590 
3591 const ProtobufCFieldDescriptor *
protobuf_c_message_descriptor_get_field_by_name(const ProtobufCMessageDescriptor * desc,const char * name)3592 protobuf_c_message_descriptor_get_field_by_name(const ProtobufCMessageDescriptor *desc,
3593 						const char *name)
3594 {
3595 	unsigned start = 0;
3596 	unsigned count;
3597 	const ProtobufCFieldDescriptor *field;
3598 
3599 	if (desc == NULL || desc->fields_sorted_by_name == NULL)
3600 		return NULL;
3601 
3602 	count = desc->n_fields;
3603 
3604 	while (count > 1) {
3605 		unsigned mid = start + count / 2;
3606 		int rv;
3607 		field = desc->fields + desc->fields_sorted_by_name[mid];
3608 		rv = strcmp(field->name, name);
3609 		if (rv == 0)
3610 			return field;
3611 		else if (rv < 0) {
3612 			count = start + count - (mid + 1);
3613 			start = mid + 1;
3614 		} else
3615 			count = mid - start;
3616 	}
3617 	if (count == 0)
3618 		return NULL;
3619 	field = desc->fields + desc->fields_sorted_by_name[start];
3620 	if (strcmp(field->name, name) == 0)
3621 		return field;
3622 	return NULL;
3623 }
3624 
3625 const ProtobufCFieldDescriptor *
protobuf_c_message_descriptor_get_field(const ProtobufCMessageDescriptor * desc,unsigned value)3626 protobuf_c_message_descriptor_get_field(const ProtobufCMessageDescriptor *desc,
3627 					unsigned value)
3628 {
3629 	int rv = int_range_lookup(desc->n_field_ranges,desc->field_ranges, value);
3630 	if (rv < 0)
3631 		return NULL;
3632 	return desc->fields + rv;
3633 }
3634 
3635 const ProtobufCMethodDescriptor *
protobuf_c_service_descriptor_get_method_by_name(const ProtobufCServiceDescriptor * desc,const char * name)3636 protobuf_c_service_descriptor_get_method_by_name(const ProtobufCServiceDescriptor *desc,
3637 						 const char *name)
3638 {
3639 	unsigned start = 0;
3640 	unsigned count;
3641 
3642 	if (desc == NULL || desc->method_indices_by_name == NULL)
3643 		return NULL;
3644 
3645 	count = desc->n_methods;
3646 
3647 	while (count > 1) {
3648 		unsigned mid = start + count / 2;
3649 		unsigned mid_index = desc->method_indices_by_name[mid];
3650 		const char *mid_name = desc->methods[mid_index].name;
3651 		int rv = strcmp(mid_name, name);
3652 
3653 		if (rv == 0)
3654 			return desc->methods + desc->method_indices_by_name[mid];
3655 		if (rv < 0) {
3656 			count = start + count - (mid + 1);
3657 			start = mid + 1;
3658 		} else {
3659 			count = mid - start;
3660 		}
3661 	}
3662 	if (count == 0)
3663 		return NULL;
3664 	if (strcmp(desc->methods[desc->method_indices_by_name[start]].name, name) == 0)
3665 		return desc->methods + desc->method_indices_by_name[start];
3666 	return NULL;
3667 }
3668