Coverage Report

Created: 2023-09-25 06:31

/src/nanopb/pb_encode.c
Line
Count
Source (jump to first uncovered line)
1
/* pb_encode.c -- encode a protobuf using minimal resources
2
 *
3
 * 2011 Petteri Aimonen <jpa@kapsi.fi>
4
 */
5
6
#include "pb.h"
7
#include "pb_encode.h"
8
#include "pb_common.h"
9
10
/* Use the GCC warn_unused_result attribute to check that all return values
11
 * are propagated correctly. On other compilers and gcc before 3.4.0 just
12
 * ignore the annotation.
13
 */
14
#if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4)
15
    #define checkreturn
16
#else
17
    #define checkreturn __attribute__((warn_unused_result))
18
#endif
19
20
/**************************************
21
 * Declarations internal to this file *
22
 **************************************/
23
static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count);
24
static bool checkreturn encode_array(pb_ostream_t *stream, pb_field_iter_t *field);
25
static bool checkreturn pb_check_proto3_default_value(const pb_field_iter_t *field);
26
static bool checkreturn encode_basic_field(pb_ostream_t *stream, const pb_field_iter_t *field);
27
static bool checkreturn encode_callback_field(pb_ostream_t *stream, const pb_field_iter_t *field);
28
static bool checkreturn encode_field(pb_ostream_t *stream, pb_field_iter_t *field);
29
static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_iter_t *field);
30
static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension);
31
static bool checkreturn pb_encode_varint_32(pb_ostream_t *stream, uint32_t low, uint32_t high);
32
static bool checkreturn pb_enc_bool(pb_ostream_t *stream, const pb_field_iter_t *field);
33
static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_iter_t *field);
34
static bool checkreturn pb_enc_fixed(pb_ostream_t *stream, const pb_field_iter_t *field);
35
static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_iter_t *field);
36
static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_iter_t *field);
37
static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_iter_t *field);
38
static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_iter_t *field);
39
40
#ifdef PB_WITHOUT_64BIT
41
#define pb_int64_t int32_t
42
#define pb_uint64_t uint32_t
43
#else
44
14.9k
#define pb_int64_t int64_t
45
36.7k
#define pb_uint64_t uint64_t
46
#endif
47
48
/*******************************
49
 * pb_ostream_t implementation *
50
 *******************************/
51
52
static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count)
53
50.4k
{
54
50.4k
    pb_byte_t *dest = (pb_byte_t*)stream->state;
55
50.4k
    stream->state = dest + count;
56
    
57
50.4k
    memcpy(dest, buf, count * sizeof(pb_byte_t));
58
    
59
50.4k
    return true;
60
50.4k
}
61
62
pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize)
63
2.72k
{
64
2.72k
    pb_ostream_t stream;
65
#ifdef PB_BUFFER_ONLY
66
    /* In PB_BUFFER_ONLY configuration the callback pointer is just int*.
67
     * NULL pointer marks a sizing field, so put a non-NULL value to mark a buffer stream.
68
     */
69
    static const int marker = 0;
70
    stream.callback = &marker;
71
#else
72
2.72k
    stream.callback = &buf_write;
73
2.72k
#endif
74
2.72k
    stream.state = buf;
75
2.72k
    stream.max_size = bufsize;
76
2.72k
    stream.bytes_written = 0;
77
2.72k
#ifndef PB_NO_ERRMSG
78
2.72k
    stream.errmsg = NULL;
79
2.72k
#endif
80
2.72k
    return stream;
81
2.72k
}
82
83
bool checkreturn pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count)
84
62.9k
{
85
62.9k
    if (count > 0 && stream->callback != NULL)
86
50.4k
    {
87
50.4k
        if (stream->bytes_written + count < stream->bytes_written ||
88
50.4k
            stream->bytes_written + count > stream->max_size)
89
0
        {
90
0
            PB_RETURN_ERROR(stream, "stream full");
91
0
        }
92
93
#ifdef PB_BUFFER_ONLY
94
        if (!buf_write(stream, buf, count))
95
            PB_RETURN_ERROR(stream, "io error");
96
#else        
97
50.4k
        if (!stream->callback(stream, buf, count))
98
0
            PB_RETURN_ERROR(stream, "io error");
99
50.4k
#endif
100
50.4k
    }
101
    
102
62.9k
    stream->bytes_written += count;
103
62.9k
    return true;
104
62.9k
}
105
106
/*************************
107
 * Encode a single field *
108
 *************************/
109
110
/* Read a bool value without causing undefined behavior even if the value
111
 * is invalid. See issue #434 and
112
 * https://stackoverflow.com/questions/27661768/weird-results-for-conditional
113
 */
114
static bool safe_read_bool(const void *pSize)
115
5.90k
{
116
5.90k
    const char *p = (const char *)pSize;
117
5.90k
    size_t i;
118
11.0k
    for (i = 0; i < sizeof(bool); i++)
119
5.90k
    {
120
5.90k
        if (p[i] != 0)
121
746
            return true;
122
5.90k
    }
123
5.15k
    return false;
124
5.90k
}
125
126
/* Encode a static array. Handles the size calculations and possible packing. */
127
static bool checkreturn encode_array(pb_ostream_t *stream, pb_field_iter_t *field)
128
51.7k
{
129
51.7k
    pb_size_t i;
130
51.7k
    pb_size_t count;
131
51.7k
#ifndef PB_ENCODE_ARRAYS_UNPACKED
132
51.7k
    size_t size;
133
51.7k
#endif
134
135
51.7k
    count = *(pb_size_t*)field->pSize;
136
137
51.7k
    if (count == 0)
138
48.4k
        return true;
139
140
3.26k
    if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size)
141
0
        PB_RETURN_ERROR(stream, "array max size exceeded");
142
    
143
3.26k
#ifndef PB_ENCODE_ARRAYS_UNPACKED
144
    /* We always pack arrays if the datatype allows it. */
145
3.26k
    if (PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE)
146
2.04k
    {
147
2.04k
        if (!pb_encode_tag(stream, PB_WT_STRING, field->tag))
148
0
            return false;
149
        
150
        /* Determine the total size of packed array. */
151
2.04k
        if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32)
152
302
        {
153
302
            size = 4 * (size_t)count;
154
302
        }
155
1.73k
        else if (PB_LTYPE(field->type) == PB_LTYPE_FIXED64)
156
250
        {
157
250
            size = 8 * (size_t)count;
158
250
        }
159
1.48k
        else
160
1.48k
        { 
161
1.48k
            pb_ostream_t sizestream = PB_OSTREAM_SIZING;
162
1.48k
            void *pData_orig = field->pData;
163
8.69k
            for (i = 0; i < count; i++)
164
7.21k
            {
165
7.21k
                if (!pb_enc_varint(&sizestream, field))
166
0
                    PB_RETURN_ERROR(stream, PB_GET_ERROR(&sizestream));
167
7.21k
                field->pData = (char*)field->pData + field->data_size;
168
7.21k
            }
169
1.48k
            field->pData = pData_orig;
170
1.48k
            size = sizestream.bytes_written;
171
1.48k
        }
172
        
173
2.04k
        if (!pb_encode_varint(stream, (pb_uint64_t)size))
174
0
            return false;
175
        
176
2.04k
        if (stream->callback == NULL)
177
0
            return pb_write(stream, NULL, size); /* Just sizing.. */
178
        
179
        /* Write the data */
180
11.6k
        for (i = 0; i < count; i++)
181
9.60k
        {
182
9.60k
            if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32 || PB_LTYPE(field->type) == PB_LTYPE_FIXED64)
183
2.39k
            {
184
2.39k
                if (!pb_enc_fixed(stream, field))
185
0
                    return false;
186
2.39k
            }
187
7.21k
            else
188
7.21k
            {
189
7.21k
                if (!pb_enc_varint(stream, field))
190
0
                    return false;
191
7.21k
            }
192
193
9.60k
            field->pData = (char*)field->pData + field->data_size;
194
9.60k
        }
195
2.04k
    }
196
1.22k
    else /* Unpacked fields */
197
1.22k
#endif
198
1.22k
    {
199
5.82k
        for (i = 0; i < count; i++)
200
4.60k
        {
201
            /* Normally the data is stored directly in the array entries, but
202
             * for pointer-type string and bytes fields, the array entries are
203
             * actually pointers themselves also. So we have to dereference once
204
             * more to get to the actual data. */
205
4.60k
            if (PB_ATYPE(field->type) == PB_ATYPE_POINTER &&
206
4.60k
                (PB_LTYPE(field->type) == PB_LTYPE_STRING ||
207
0
                 PB_LTYPE(field->type) == PB_LTYPE_BYTES))
208
0
            {
209
0
                bool status;
210
0
                void *pData_orig = field->pData;
211
0
                field->pData = *(void* const*)field->pData;
212
213
0
                if (!field->pData)
214
0
                {
215
                    /* Null pointer in array is treated as empty string / bytes */
216
0
                    status = pb_encode_tag_for_field(stream, field) &&
217
0
                             pb_encode_varint(stream, 0);
218
0
                }
219
0
                else
220
0
                {
221
0
                    status = encode_basic_field(stream, field);
222
0
                }
223
224
0
                field->pData = pData_orig;
225
226
0
                if (!status)
227
0
                    return false;
228
0
            }
229
4.60k
            else
230
4.60k
            {
231
4.60k
                if (!encode_basic_field(stream, field))
232
0
                    return false;
233
4.60k
            }
234
4.60k
            field->pData = (char*)field->pData + field->data_size;
235
4.60k
        }
236
1.22k
    }
237
    
238
3.26k
    return true;
239
3.26k
}
240
241
/* In proto3, all fields are optional and are only encoded if their value is "non-zero".
242
 * This function implements the check for the zero value. */
243
static bool checkreturn pb_check_proto3_default_value(const pb_field_iter_t *field)
244
91.5k
{
245
91.5k
    pb_type_t type = field->type;
246
247
91.5k
    if (PB_ATYPE(type) == PB_ATYPE_STATIC)
248
91.5k
    {
249
91.5k
        if (PB_HTYPE(type) == PB_HTYPE_REQUIRED)
250
0
        {
251
            /* Required proto2 fields inside proto3 submessage, pretty rare case */
252
0
            return false;
253
0
        }
254
91.5k
        else if (PB_HTYPE(type) == PB_HTYPE_REPEATED)
255
0
        {
256
            /* Repeated fields inside proto3 submessage: present if count != 0 */
257
0
            return *(const pb_size_t*)field->pSize == 0;
258
0
        }
259
91.5k
        else if (PB_HTYPE(type) == PB_HTYPE_ONEOF)
260
0
        {
261
            /* Oneof fields */
262
0
            return *(const pb_size_t*)field->pSize == 0;
263
0
        }
264
91.5k
        else if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && field->pSize != NULL)
265
0
        {
266
            /* Proto2 optional fields inside proto3 message, or proto3
267
             * submessage fields. */
268
0
            return safe_read_bool(field->pSize) == false;
269
0
        }
270
91.5k
        else if (field->descriptor->default_value)
271
0
        {
272
            /* Proto3 messages do not have default values, but proto2 messages
273
             * can contain optional fields without has_fields (generator option 'proto3').
274
             * In this case they must always be encoded, to make sure that the
275
             * non-zero default value is overwritten.
276
             */
277
0
            return false;
278
0
        }
279
280
        /* Rest is proto3 singular fields */
281
91.5k
        if (PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE)
282
77.3k
        {
283
            /* Simple integer / float fields */
284
77.3k
            pb_size_t i;
285
77.3k
            const char *p = (const char*)field->pData;
286
445k
            for (i = 0; i < field->data_size; i++)
287
377k
            {
288
377k
                if (p[i] != 0)
289
8.74k
                {
290
8.74k
                    return false;
291
8.74k
                }
292
377k
            }
293
294
68.5k
            return true;
295
77.3k
        }
296
14.2k
        else if (PB_LTYPE(type) == PB_LTYPE_BYTES)
297
2.72k
        {
298
2.72k
            const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)field->pData;
299
2.72k
            return bytes->size == 0;
300
2.72k
        }
301
11.5k
        else if (PB_LTYPE(type) == PB_LTYPE_STRING)
302
6.07k
        {
303
6.07k
            return *(const char*)field->pData == '\0';
304
6.07k
        }
305
5.44k
        else if (PB_LTYPE(type) == PB_LTYPE_FIXED_LENGTH_BYTES)
306
2.72k
        {
307
            /* Fixed length bytes is only empty if its length is fixed
308
             * as 0. Which would be pretty strange, but we can check
309
             * it anyway. */
310
2.72k
            return field->data_size == 0;
311
2.72k
        }
312
2.72k
        else if (PB_LTYPE_IS_SUBMSG(type))
313
2.72k
        {
314
            /* Check all fields in the submessage to find if any of them
315
             * are non-zero. The comparison cannot be done byte-per-byte
316
             * because the C struct may contain padding bytes that must
317
             * be skipped. Note that usually proto3 submessages have
318
             * a separate has_field that is checked earlier in this if.
319
             */
320
2.72k
            pb_field_iter_t iter;
321
2.72k
            if (pb_field_iter_begin(&iter, field->submsg_desc, field->pData))
322
2.72k
            {
323
2.72k
                do
324
25.5k
                {
325
25.5k
                    if (!pb_check_proto3_default_value(&iter))
326
210
                    {
327
210
                        return false;
328
210
                    }
329
25.5k
                } while (pb_field_iter_next(&iter));
330
2.72k
            }
331
2.51k
            return true;
332
2.72k
        }
333
91.5k
    }
334
0
    else if (PB_ATYPE(type) == PB_ATYPE_POINTER)
335
0
    {
336
0
        return field->pData == NULL;
337
0
    }
338
0
    else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK)
339
0
    {
340
0
        if (PB_LTYPE(type) == PB_LTYPE_EXTENSION)
341
0
        {
342
0
            const pb_extension_t *extension = *(const pb_extension_t* const *)field->pData;
343
0
            return extension == NULL;
344
0
        }
345
0
        else if (field->descriptor->field_callback == pb_default_field_callback)
346
0
        {
347
0
            pb_callback_t *pCallback = (pb_callback_t*)field->pData;
348
0
            return pCallback->funcs.encode == NULL;
349
0
        }
350
0
        else
351
0
        {
352
0
            return field->descriptor->field_callback == NULL;
353
0
        }
354
0
    }
355
356
0
    return false; /* Not typically reached, safe default for weird special cases. */
357
91.5k
}
358
359
/* Encode a field with static or pointer allocation, i.e. one whose data
360
 * is available to the encoder directly. */
361
static bool checkreturn encode_basic_field(pb_ostream_t *stream, const pb_field_iter_t *field)
362
17.7k
{
363
17.7k
    if (!field->pData)
364
0
    {
365
        /* Missing pointer field */
366
0
        return true;
367
0
    }
368
369
17.7k
    if (!pb_encode_tag_for_field(stream, field))
370
0
        return false;
371
372
17.7k
    switch (PB_LTYPE(field->type))
373
17.7k
    {
374
454
        case PB_LTYPE_BOOL:
375
454
            return pb_enc_bool(stream, field);
376
377
3.37k
        case PB_LTYPE_VARINT:
378
5.05k
        case PB_LTYPE_UVARINT:
379
6.16k
        case PB_LTYPE_SVARINT:
380
6.16k
            return pb_enc_varint(stream, field);
381
382
1.35k
        case PB_LTYPE_FIXED32:
383
1.91k
        case PB_LTYPE_FIXED64:
384
1.91k
            return pb_enc_fixed(stream, field);
385
386
904
        case PB_LTYPE_BYTES:
387
904
            return pb_enc_bytes(stream, field);
388
389
1.53k
        case PB_LTYPE_STRING:
390
1.53k
            return pb_enc_string(stream, field);
391
392
2.78k
        case PB_LTYPE_SUBMESSAGE:
393
2.78k
        case PB_LTYPE_SUBMSG_W_CB:
394
2.78k
            return pb_enc_submessage(stream, field);
395
396
4.02k
        case PB_LTYPE_FIXED_LENGTH_BYTES:
397
4.02k
            return pb_enc_fixed_length_bytes(stream, field);
398
399
0
        default:
400
0
            PB_RETURN_ERROR(stream, "invalid field type");
401
17.7k
    }
402
17.7k
}
403
404
/* Encode a field with callback semantics. This means that a user function is
405
 * called to provide and encode the actual data. */
406
static bool checkreturn encode_callback_field(pb_ostream_t *stream, const pb_field_iter_t *field)
407
0
{
408
0
    if (field->descriptor->field_callback != NULL)
409
0
    {
410
0
        if (!field->descriptor->field_callback(NULL, stream, field))
411
0
            PB_RETURN_ERROR(stream, "callback error");
412
0
    }
413
0
    return true;
414
0
}
415
416
/* Encode a single field of any callback, pointer or static type. */
417
static bool checkreturn encode_field(pb_ostream_t *stream, pb_field_iter_t *field)
418
131k
{
419
    /* Check field presence */
420
131k
    if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF)
421
8.17k
    {
422
8.17k
        if (*(const pb_size_t*)field->pSize != field->tag)
423
7.85k
        {
424
            /* Different type oneof field */
425
7.85k
            return true;
426
7.85k
        }
427
8.17k
    }
428
123k
    else if (PB_HTYPE(field->type) == PB_HTYPE_OPTIONAL)
429
71.4k
    {
430
71.4k
        if (field->pSize)
431
5.44k
        {
432
5.44k
            if (safe_read_bool(field->pSize) == false)
433
5.15k
            {
434
                /* Missing optional field */
435
5.15k
                return true;
436
5.15k
            }
437
5.44k
        }
438
66.0k
        else if (PB_ATYPE(field->type) == PB_ATYPE_STATIC)
439
66.0k
        {
440
            /* Proto3 singular field */
441
66.0k
            if (pb_check_proto3_default_value(field))
442
53.4k
                return true;
443
66.0k
        }
444
71.4k
    }
445
446
64.9k
    if (!field->pData)
447
0
    {
448
0
        if (PB_HTYPE(field->type) == PB_HTYPE_REQUIRED)
449
0
            PB_RETURN_ERROR(stream, "missing required field");
450
451
        /* Pointer field set to NULL */
452
0
        return true;
453
0
    }
454
455
    /* Then encode field contents */
456
64.9k
    if (PB_ATYPE(field->type) == PB_ATYPE_CALLBACK)
457
0
    {
458
0
        return encode_callback_field(stream, field);
459
0
    }
460
64.9k
    else if (PB_HTYPE(field->type) == PB_HTYPE_REPEATED)
461
51.7k
    {
462
51.7k
        return encode_array(stream, field);
463
51.7k
    }
464
13.1k
    else
465
13.1k
    {
466
13.1k
        return encode_basic_field(stream, field);
467
13.1k
    }
468
64.9k
}
469
470
/* Default handler for extension fields. Expects to have a pb_msgdesc_t
471
 * pointer in the extension->type->arg field, pointing to a message with
472
 * only one field in it.  */
473
static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension)
474
0
{
475
0
    pb_field_iter_t iter;
476
477
0
    if (!pb_field_iter_begin_extension_const(&iter, extension))
478
0
        PB_RETURN_ERROR(stream, "invalid extension");
479
480
0
    return encode_field(stream, &iter);
481
0
}
482
483
484
/* Walk through all the registered extensions and give them a chance
485
 * to encode themselves. */
486
static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_iter_t *field)
487
0
{
488
0
    const pb_extension_t *extension = *(const pb_extension_t* const *)field->pData;
489
490
0
    while (extension)
491
0
    {
492
0
        bool status;
493
0
        if (extension->type->encode)
494
0
            status = extension->type->encode(stream, extension);
495
0
        else
496
0
            status = default_extension_encoder(stream, extension);
497
498
0
        if (!status)
499
0
            return false;
500
        
501
0
        extension = extension->next;
502
0
    }
503
    
504
0
    return true;
505
0
}
506
507
/*********************
508
 * Encode all fields *
509
 *********************/
510
511
bool checkreturn pb_encode(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct)
512
8.28k
{
513
8.28k
    pb_field_iter_t iter;
514
8.28k
    if (!pb_field_iter_begin_const(&iter, fields, src_struct))
515
1.79k
        return true; /* Empty message type */
516
    
517
131k
    do {
518
131k
        if (PB_LTYPE(iter.type) == PB_LTYPE_EXTENSION)
519
0
        {
520
            /* Special case for the extension field placeholder */
521
0
            if (!encode_extension_field(stream, &iter))
522
0
                return false;
523
0
        }
524
131k
        else
525
131k
        {
526
            /* Regular field */
527
131k
            if (!encode_field(stream, &iter))
528
0
                return false;
529
131k
        }
530
131k
    } while (pb_field_iter_next(&iter));
531
    
532
6.49k
    return true;
533
6.49k
}
534
535
bool checkreturn pb_encode_ex(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct, unsigned int flags)
536
0
{
537
0
  if ((flags & PB_ENCODE_DELIMITED) != 0)
538
0
  {
539
0
    return pb_encode_submessage(stream, fields, src_struct);
540
0
  }
541
0
  else if ((flags & PB_ENCODE_NULLTERMINATED) != 0)
542
0
  {
543
0
    const pb_byte_t zero = 0;
544
545
0
    if (!pb_encode(stream, fields, src_struct))
546
0
        return false;
547
548
0
    return pb_write(stream, &zero, 1);
549
0
  }
550
0
  else
551
0
  {
552
0
    return pb_encode(stream, fields, src_struct);
553
0
  }
554
0
}
555
556
bool pb_get_encoded_size(size_t *size, const pb_msgdesc_t *fields, const void *src_struct)
557
0
{
558
0
    pb_ostream_t stream = PB_OSTREAM_SIZING;
559
    
560
0
    if (!pb_encode(&stream, fields, src_struct))
561
0
        return false;
562
    
563
0
    *size = stream.bytes_written;
564
0
    return true;
565
0
}
566
567
/********************
568
 * Helper functions *
569
 ********************/
570
571
/* This function avoids 64-bit shifts as they are quite slow on many platforms. */
572
static bool checkreturn pb_encode_varint_32(pb_ostream_t *stream, uint32_t low, uint32_t high)
573
20.3k
{
574
20.3k
    size_t i = 0;
575
20.3k
    pb_byte_t buffer[10];
576
20.3k
    pb_byte_t byte = (pb_byte_t)(low & 0x7F);
577
20.3k
    low >>= 7;
578
579
61.9k
    while (i < 4 && (low != 0 || high != 0))
580
41.5k
    {
581
41.5k
        byte |= 0x80;
582
41.5k
        buffer[i++] = byte;
583
41.5k
        byte = (pb_byte_t)(low & 0x7F);
584
41.5k
        low >>= 7;
585
41.5k
    }
586
587
20.3k
    if (high)
588
5.24k
    {
589
5.24k
        byte = (pb_byte_t)(byte | ((high & 0x07) << 4));
590
5.24k
        high >>= 3;
591
592
26.0k
        while (high)
593
20.8k
        {
594
20.8k
            byte |= 0x80;
595
20.8k
            buffer[i++] = byte;
596
20.8k
            byte = (pb_byte_t)(high & 0x7F);
597
20.8k
            high >>= 7;
598
20.8k
        }
599
5.24k
    }
600
601
20.3k
    buffer[i++] = byte;
602
603
20.3k
    return pb_write(stream, buffer, i);
604
20.3k
}
605
606
bool checkreturn pb_encode_varint(pb_ostream_t *stream, pb_uint64_t value)
607
52.1k
{
608
52.1k
    if (value <= 0x7F)
609
31.7k
    {
610
        /* Fast path: single byte */
611
31.7k
        pb_byte_t byte = (pb_byte_t)value;
612
31.7k
        return pb_write(stream, &byte, 1);
613
31.7k
    }
614
20.3k
    else
615
20.3k
    {
616
#ifdef PB_WITHOUT_64BIT
617
        return pb_encode_varint_32(stream, value, 0);
618
#else
619
20.3k
        return pb_encode_varint_32(stream, (uint32_t)value, (uint32_t)(value >> 32));
620
20.3k
#endif
621
20.3k
    }
622
52.1k
}
623
624
bool checkreturn pb_encode_svarint(pb_ostream_t *stream, pb_int64_t value)
625
5.66k
{
626
5.66k
    pb_uint64_t zigzagged;
627
5.66k
    pb_uint64_t mask = ((pb_uint64_t)-1) >> 1; /* Satisfy clang -fsanitize=integer */
628
5.66k
    if (value < 0)
629
2.68k
        zigzagged = ~(((pb_uint64_t)value & mask) << 1);
630
2.97k
    else
631
2.97k
        zigzagged = (pb_uint64_t)value << 1;
632
    
633
5.66k
    return pb_encode_varint(stream, zigzagged);
634
5.66k
}
635
636
bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value)
637
2.77k
{
638
2.77k
#if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1
639
    /* Fast path if we know that we're on little endian */
640
2.77k
    return pb_write(stream, (const pb_byte_t*)value, 4);
641
#else
642
    uint32_t val = *(const uint32_t*)value;
643
    pb_byte_t bytes[4];
644
    bytes[0] = (pb_byte_t)(val & 0xFF);
645
    bytes[1] = (pb_byte_t)((val >> 8) & 0xFF);
646
    bytes[2] = (pb_byte_t)((val >> 16) & 0xFF);
647
    bytes[3] = (pb_byte_t)((val >> 24) & 0xFF);
648
    return pb_write(stream, bytes, 4);
649
#endif
650
2.77k
}
651
652
#ifndef PB_WITHOUT_64BIT
653
bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value)
654
1.53k
{
655
1.53k
#if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1
656
    /* Fast path if we know that we're on little endian */
657
1.53k
    return pb_write(stream, (const pb_byte_t*)value, 8);
658
#else
659
    uint64_t val = *(const uint64_t*)value;
660
    pb_byte_t bytes[8];
661
    bytes[0] = (pb_byte_t)(val & 0xFF);
662
    bytes[1] = (pb_byte_t)((val >> 8) & 0xFF);
663
    bytes[2] = (pb_byte_t)((val >> 16) & 0xFF);
664
    bytes[3] = (pb_byte_t)((val >> 24) & 0xFF);
665
    bytes[4] = (pb_byte_t)((val >> 32) & 0xFF);
666
    bytes[5] = (pb_byte_t)((val >> 40) & 0xFF);
667
    bytes[6] = (pb_byte_t)((val >> 48) & 0xFF);
668
    bytes[7] = (pb_byte_t)((val >> 56) & 0xFF);
669
    return pb_write(stream, bytes, 8);
670
#endif
671
1.53k
}
672
#endif
673
674
bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number)
675
19.8k
{
676
19.8k
    pb_uint64_t tag = ((pb_uint64_t)field_number << 3) | wiretype;
677
19.8k
    return pb_encode_varint(stream, tag);
678
19.8k
}
679
680
bool pb_encode_tag_for_field ( pb_ostream_t* stream, const pb_field_iter_t* field )
681
17.7k
{
682
17.7k
    pb_wire_type_t wiretype;
683
17.7k
    switch (PB_LTYPE(field->type))
684
17.7k
    {
685
454
        case PB_LTYPE_BOOL:
686
3.82k
        case PB_LTYPE_VARINT:
687
5.50k
        case PB_LTYPE_UVARINT:
688
6.61k
        case PB_LTYPE_SVARINT:
689
6.61k
            wiretype = PB_WT_VARINT;
690
6.61k
            break;
691
        
692
1.35k
        case PB_LTYPE_FIXED32:
693
1.35k
            wiretype = PB_WT_32BIT;
694
1.35k
            break;
695
        
696
568
        case PB_LTYPE_FIXED64:
697
568
            wiretype = PB_WT_64BIT;
698
568
            break;
699
        
700
904
        case PB_LTYPE_BYTES:
701
2.43k
        case PB_LTYPE_STRING:
702
5.22k
        case PB_LTYPE_SUBMESSAGE:
703
5.22k
        case PB_LTYPE_SUBMSG_W_CB:
704
9.24k
        case PB_LTYPE_FIXED_LENGTH_BYTES:
705
9.24k
            wiretype = PB_WT_STRING;
706
9.24k
            break;
707
        
708
0
        default:
709
0
            PB_RETURN_ERROR(stream, "invalid field type");
710
17.7k
    }
711
    
712
17.7k
    return pb_encode_tag(stream, wiretype, field->tag);
713
17.7k
}
714
715
bool checkreturn pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size)
716
6.46k
{
717
6.46k
    if (!pb_encode_varint(stream, (pb_uint64_t)size))
718
0
        return false;
719
    
720
6.46k
    return pb_write(stream, buffer, size);
721
6.46k
}
722
723
bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct)
724
2.78k
{
725
    /* First calculate the message size using a non-writing substream. */
726
2.78k
    pb_ostream_t substream = PB_OSTREAM_SIZING;
727
2.78k
    size_t size;
728
2.78k
    bool status;
729
    
730
2.78k
    if (!pb_encode(&substream, fields, src_struct))
731
0
    {
732
0
#ifndef PB_NO_ERRMSG
733
0
        stream->errmsg = substream.errmsg;
734
0
#endif
735
0
        return false;
736
0
    }
737
    
738
2.78k
    size = substream.bytes_written;
739
    
740
2.78k
    if (!pb_encode_varint(stream, (pb_uint64_t)size))
741
0
        return false;
742
    
743
2.78k
    if (stream->callback == NULL)
744
0
        return pb_write(stream, NULL, size); /* Just sizing */
745
    
746
2.78k
    if (stream->bytes_written + size > stream->max_size)
747
0
        PB_RETURN_ERROR(stream, "stream full");
748
        
749
    /* Use a substream to verify that a callback doesn't write more than
750
     * what it did the first time. */
751
2.78k
    substream.callback = stream->callback;
752
2.78k
    substream.state = stream->state;
753
2.78k
    substream.max_size = size;
754
2.78k
    substream.bytes_written = 0;
755
2.78k
#ifndef PB_NO_ERRMSG
756
2.78k
    substream.errmsg = NULL;
757
2.78k
#endif
758
    
759
2.78k
    status = pb_encode(&substream, fields, src_struct);
760
    
761
2.78k
    stream->bytes_written += substream.bytes_written;
762
2.78k
    stream->state = substream.state;
763
2.78k
#ifndef PB_NO_ERRMSG
764
2.78k
    stream->errmsg = substream.errmsg;
765
2.78k
#endif
766
    
767
2.78k
    if (substream.bytes_written != size)
768
0
        PB_RETURN_ERROR(stream, "submsg size changed");
769
    
770
2.78k
    return status;
771
2.78k
}
772
773
/* Field encoders */
774
775
static bool checkreturn pb_enc_bool(pb_ostream_t *stream, const pb_field_iter_t *field)
776
454
{
777
454
    uint32_t value = safe_read_bool(field->pData) ? 1 : 0;
778
454
    PB_UNUSED(field);
779
454
    return pb_encode_varint(stream, value);
780
454
}
781
782
static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_iter_t *field)
783
20.5k
{
784
20.5k
    if (PB_LTYPE(field->type) == PB_LTYPE_UVARINT)
785
5.63k
    {
786
        /* Perform unsigned integer extension */
787
5.63k
        pb_uint64_t value = 0;
788
789
5.63k
        if (field->data_size == sizeof(uint_least8_t))
790
0
            value = *(const uint_least8_t*)field->pData;
791
5.63k
        else if (field->data_size == sizeof(uint_least16_t))
792
0
            value = *(const uint_least16_t*)field->pData;
793
5.63k
        else if (field->data_size == sizeof(uint32_t))
794
3.16k
            value = *(const uint32_t*)field->pData;
795
2.47k
        else if (field->data_size == sizeof(pb_uint64_t))
796
2.47k
            value = *(const pb_uint64_t*)field->pData;
797
0
        else
798
0
            PB_RETURN_ERROR(stream, "invalid data_size");
799
800
5.63k
        return pb_encode_varint(stream, value);
801
5.63k
    }
802
14.9k
    else
803
14.9k
    {
804
        /* Perform signed integer extension */
805
14.9k
        pb_int64_t value = 0;
806
807
14.9k
        if (field->data_size == sizeof(int_least8_t))
808
1.22k
            value = *(const int_least8_t*)field->pData;
809
13.7k
        else if (field->data_size == sizeof(int_least16_t))
810
0
            value = *(const int_least16_t*)field->pData;
811
13.7k
        else if (field->data_size == sizeof(int32_t))
812
7.66k
            value = *(const int32_t*)field->pData;
813
6.05k
        else if (field->data_size == sizeof(pb_int64_t))
814
6.05k
            value = *(const pb_int64_t*)field->pData;
815
0
        else
816
0
            PB_RETURN_ERROR(stream, "invalid data_size");
817
818
14.9k
        if (PB_LTYPE(field->type) == PB_LTYPE_SVARINT)
819
5.66k
            return pb_encode_svarint(stream, value);
820
#ifdef PB_WITHOUT_64BIT
821
        else if (value < 0)
822
            return pb_encode_varint_32(stream, (uint32_t)value, (uint32_t)-1);
823
#endif
824
9.28k
        else
825
9.28k
            return pb_encode_varint(stream, (pb_uint64_t)value);
826
827
14.9k
    }
828
20.5k
}
829
830
static bool checkreturn pb_enc_fixed(pb_ostream_t *stream, const pb_field_iter_t *field)
831
4.31k
{
832
#ifdef PB_CONVERT_DOUBLE_FLOAT
833
    if (field->data_size == sizeof(float) && PB_LTYPE(field->type) == PB_LTYPE_FIXED64)
834
    {
835
        return pb_encode_float_as_double(stream, *(float*)field->pData);
836
    }
837
#endif
838
839
4.31k
    if (field->data_size == sizeof(uint32_t))
840
2.77k
    {
841
2.77k
        return pb_encode_fixed32(stream, field->pData);
842
2.77k
    }
843
1.53k
#ifndef PB_WITHOUT_64BIT
844
1.53k
    else if (field->data_size == sizeof(uint64_t))
845
1.53k
    {
846
1.53k
        return pb_encode_fixed64(stream, field->pData);
847
1.53k
    }
848
0
#endif
849
0
    else
850
0
    {
851
0
        PB_RETURN_ERROR(stream, "invalid data_size");
852
0
    }
853
4.31k
}
854
855
static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_iter_t *field)
856
904
{
857
904
    const pb_bytes_array_t *bytes = NULL;
858
859
904
    bytes = (const pb_bytes_array_t*)field->pData;
860
    
861
904
    if (bytes == NULL)
862
0
    {
863
        /* Treat null pointer as an empty bytes field */
864
0
        return pb_encode_string(stream, NULL, 0);
865
0
    }
866
    
867
904
    if (PB_ATYPE(field->type) == PB_ATYPE_STATIC &&
868
904
        bytes->size > field->data_size - offsetof(pb_bytes_array_t, bytes))
869
0
    {
870
0
        PB_RETURN_ERROR(stream, "bytes size exceeded");
871
0
    }
872
    
873
904
    return pb_encode_string(stream, bytes->bytes, (size_t)bytes->size);
874
904
}
875
876
static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_iter_t *field)
877
1.53k
{
878
1.53k
    size_t size = 0;
879
1.53k
    size_t max_size = (size_t)field->data_size;
880
1.53k
    const char *str = (const char*)field->pData;
881
    
882
1.53k
    if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
883
0
    {
884
0
        max_size = (size_t)-1;
885
0
    }
886
1.53k
    else
887
1.53k
    {
888
        /* pb_dec_string() assumes string fields end with a null
889
         * terminator when the type isn't PB_ATYPE_POINTER, so we
890
         * shouldn't allow more than max-1 bytes to be written to
891
         * allow space for the null terminator.
892
         */
893
1.53k
        if (max_size == 0)
894
0
            PB_RETURN_ERROR(stream, "zero-length string");
895
896
1.53k
        max_size -= 1;
897
1.53k
    }
898
899
900
1.53k
    if (str == NULL)
901
0
    {
902
0
        size = 0; /* Treat null pointer as an empty string */
903
0
    }
904
1.53k
    else
905
1.53k
    {
906
1.53k
        const char *p = str;
907
908
        /* strnlen() is not always available, so just use a loop */
909
13.0k
        while (size < max_size && *p != '\0')
910
11.4k
        {
911
11.4k
            size++;
912
11.4k
            p++;
913
11.4k
        }
914
915
1.53k
        if (*p != '\0')
916
0
        {
917
0
            PB_RETURN_ERROR(stream, "unterminated string");
918
0
        }
919
1.53k
    }
920
921
#ifdef PB_VALIDATE_UTF8
922
    if (!pb_validate_utf8(str))
923
        PB_RETURN_ERROR(stream, "invalid utf8");
924
#endif
925
926
1.53k
    return pb_encode_string(stream, (const pb_byte_t*)str, size);
927
1.53k
}
928
929
static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_iter_t *field)
930
2.78k
{
931
2.78k
    if (field->submsg_desc == NULL)
932
0
        PB_RETURN_ERROR(stream, "invalid field descriptor");
933
934
2.78k
    if (PB_LTYPE(field->type) == PB_LTYPE_SUBMSG_W_CB && field->pSize != NULL)
935
0
    {
936
        /* Message callback is stored right before pSize. */
937
0
        pb_callback_t *callback = (pb_callback_t*)field->pSize - 1;
938
0
        if (callback->funcs.encode)
939
0
        {
940
0
            if (!callback->funcs.encode(stream, field, &callback->arg))
941
0
                return false;
942
0
        }
943
0
    }
944
    
945
2.78k
    return pb_encode_submessage(stream, field->submsg_desc, field->pData);
946
2.78k
}
947
948
static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_iter_t *field)
949
4.02k
{
950
4.02k
    return pb_encode_string(stream, (const pb_byte_t*)field->pData, (size_t)field->data_size);
951
4.02k
}
952
953
#ifdef PB_CONVERT_DOUBLE_FLOAT
954
bool pb_encode_float_as_double(pb_ostream_t *stream, float value)
955
{
956
    union { float f; uint32_t i; } in;
957
    uint_least8_t sign;
958
    int exponent;
959
    uint64_t mantissa;
960
961
    in.f = value;
962
963
    /* Decompose input value */
964
    sign = (uint_least8_t)((in.i >> 31) & 1);
965
    exponent = (int)((in.i >> 23) & 0xFF) - 127;
966
    mantissa = in.i & 0x7FFFFF;
967
968
    if (exponent == 128)
969
    {
970
        /* Special value (NaN etc.) */
971
        exponent = 1024;
972
    }
973
    else if (exponent == -127)
974
    {
975
        if (!mantissa)
976
        {
977
            /* Zero */
978
            exponent = -1023;
979
        }
980
        else
981
        {
982
            /* Denormalized */
983
            mantissa <<= 1;
984
            while (!(mantissa & 0x800000))
985
            {
986
                mantissa <<= 1;
987
                exponent--;
988
            }
989
            mantissa &= 0x7FFFFF;
990
        }
991
    }
992
993
    /* Combine fields */
994
    mantissa <<= 29;
995
    mantissa |= (uint64_t)(exponent + 1023) << 52;
996
    mantissa |= (uint64_t)sign << 63;
997
998
    return pb_encode_fixed64(stream, &mantissa);
999
}
1000
#endif