LCOV - code coverage report
Current view: top level - flamenco/nanopb - pb_decode.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 1072 0.0 %
Date: 2025-03-20 12:08:36 Functions: 0 41 0.0 %

          Line data    Source code
       1             : /* pb_decode.c -- decode a protobuf using minimal resources
       2             :  *
       3             :  * 2011 Petteri Aimonen <jpa@kapsi.fi>
       4             :  */
       5             : 
       6             : /* Use the GCC warn_unused_result attribute to check that all return values
       7             :  * are propagated correctly. On other compilers, gcc before 3.4.0 and iar
       8             :  * before 9.40.1 just ignore the annotation.
       9             :  */
      10             : #if (defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))) || \
      11             :     (defined(__IAR_SYSTEMS_ICC__) && (__VER__ >= 9040001))
      12             :     #define checkreturn __attribute__((warn_unused_result))
      13             : #else
      14             :     #define checkreturn
      15             : #endif
      16             : 
      17             : #include "pb_firedancer.h"
      18             : #include "pb_decode.h"
      19             : #include "pb_common.h"
      20             : 
      21             : /**************************************
      22             :  * Declarations internal to this file *
      23             :  **************************************/
      24             : 
      25             : static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count);
      26             : static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof);
      27             : static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size);
      28             : static bool checkreturn decode_basic_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field);
      29             : static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field);
      30             : static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field);
      31             : static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field);
      32             : static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field);
      33             : static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type);
      34             : static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_extension_t *extension);
      35             : static bool pb_field_set_to_default(pb_field_iter_t *field);
      36             : static bool pb_message_set_to_defaults(pb_field_iter_t *iter);
      37             : static bool checkreturn pb_dec_bool(pb_istream_t *stream, const pb_field_iter_t *field);
      38             : static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_iter_t *field);
      39             : static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_iter_t *field);
      40             : static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_iter_t *field);
      41             : static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_iter_t *field);
      42             : static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_iter_t *field);
      43             : static bool checkreturn pb_skip_varint(pb_istream_t *stream);
      44             : static bool checkreturn pb_skip_string(pb_istream_t *stream);
      45             : 
      46             : #ifdef PB_ENABLE_MALLOC
      47             : static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size);
      48             : static void initialize_pointer_field(void *pItem, pb_field_iter_t *field);
      49             : static bool checkreturn pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *field);
      50             : static void pb_release_single_field(pb_field_iter_t *field);
      51             : #endif
      52             : 
      53             : #ifdef PB_WITHOUT_64BIT
      54             : #define pb_int64_t int32_t
      55             : #define pb_uint64_t uint32_t
      56             : #else
      57           0 : #define pb_int64_t int64_t
      58           0 : #define pb_uint64_t uint64_t
      59             : #endif
      60             : 
      61             : typedef struct {
      62             :     uint32_t bitfield[(PB_MAX_REQUIRED_FIELDS + 31) / 32];
      63             : } pb_fields_seen_t;
      64             : 
      65             : /*******************************
      66             :  * pb_istream_t implementation *
      67             :  *******************************/
      68             : 
      69             : static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count)
      70           0 : {
      71           0 :     const pb_byte_t *source = (const pb_byte_t*)stream->state;
      72           0 :     stream->state = (pb_byte_t*)stream->state + count;
      73             :     
      74           0 :     if (buf != NULL)
      75           0 :     {
      76           0 :         memcpy(buf, source, count * sizeof(pb_byte_t));
      77           0 :     }
      78             :     
      79           0 :     return true;
      80           0 : }
      81             : 
      82             : bool checkreturn pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count)
      83           0 : {
      84           0 :     if (count == 0)
      85           0 :         return true;
      86             : 
      87             : #ifndef PB_BUFFER_ONLY
      88             :         if (buf == NULL && stream->callback != buf_read)
      89             :         {
      90             :                 /* Skip input bytes */
      91             :                 pb_byte_t tmp[16];
      92             :                 while (count > 16)
      93             :                 {
      94             :                         if (!pb_read(stream, tmp, 16))
      95             :                                 return false;
      96             :                         
      97             :                         count -= 16;
      98             :                 }
      99             :                 
     100             :                 return pb_read(stream, tmp, count);
     101             :         }
     102             : #endif
     103             : 
     104           0 :     if (stream->bytes_left < count)
     105           0 :         PB_RETURN_ERROR(stream, "end-of-stream");
     106             :     
     107             : #ifndef PB_BUFFER_ONLY
     108             :     if (!stream->callback(stream, buf, count))
     109             :         PB_RETURN_ERROR(stream, "io error");
     110             : #else
     111           0 :     if (!buf_read(stream, buf, count))
     112           0 :         return false;
     113           0 : #endif
     114             :     
     115           0 :     if (stream->bytes_left < count)
     116           0 :         stream->bytes_left = 0;
     117           0 :     else
     118           0 :         stream->bytes_left -= count;
     119             : 
     120           0 :     return true;
     121           0 : }
     122             : 
     123             : /* Read a single byte from input stream. buf may not be NULL.
     124             :  * This is an optimization for the varint decoding. */
     125             : static bool checkreturn pb_readbyte(pb_istream_t *stream, pb_byte_t *buf)
     126           0 : {
     127           0 :     if (stream->bytes_left == 0)
     128           0 :         PB_RETURN_ERROR(stream, "end-of-stream");
     129             : 
     130             : #ifndef PB_BUFFER_ONLY
     131             :     if (!stream->callback(stream, buf, 1))
     132             :         PB_RETURN_ERROR(stream, "io error");
     133             : #else
     134           0 :     *buf = *(const pb_byte_t*)stream->state;
     135           0 :     stream->state = (pb_byte_t*)stream->state + 1;
     136           0 : #endif
     137             : 
     138           0 :     stream->bytes_left--;
     139             :     
     140           0 :     return true;    
     141           0 : }
     142             : 
     143             : pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t msglen)
     144           0 : {
     145           0 :     pb_istream_t stream;
     146             :     /* Cast away the const from buf without a compiler error.  We are
     147             :      * careful to use it only in a const manner in the callbacks.
     148             :      */
     149           0 :     union {
     150           0 :         void *state;
     151           0 :         const void *c_state;
     152           0 :     } state;
     153           0 : #ifdef PB_BUFFER_ONLY
     154           0 :     stream.callback = NULL;
     155             : #else
     156             :     stream.callback = &buf_read;
     157             : #endif
     158           0 :     state.c_state = buf;
     159           0 :     stream.state = state.state;
     160           0 :     stream.bytes_left = msglen;
     161           0 : #ifndef PB_NO_ERRMSG
     162           0 :     stream.errmsg = NULL;
     163           0 : #endif
     164           0 :     return stream;
     165           0 : }
     166             : 
     167             : /********************
     168             :  * Helper functions *
     169             :  ********************/
     170             : 
     171             : static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof)
     172           0 : {
     173           0 :     pb_byte_t byte;
     174           0 :     uint32_t result;
     175             :     
     176           0 :     if (!pb_readbyte(stream, &byte))
     177           0 :     {
     178           0 :         if (stream->bytes_left == 0)
     179           0 :         {
     180           0 :             if (eof)
     181           0 :             {
     182           0 :                 *eof = true;
     183           0 :             }
     184           0 :         }
     185             : 
     186           0 :         return false;
     187           0 :     }
     188             :     
     189           0 :     if ((byte & 0x80) == 0)
     190           0 :     {
     191             :         /* Quick case, 1 byte value */
     192           0 :         result = byte;
     193           0 :     }
     194           0 :     else
     195           0 :     {
     196             :         /* Multibyte case */
     197           0 :         uint_fast8_t bitpos = 7;
     198           0 :         result = byte & 0x7F;
     199             :         
     200           0 :         do
     201           0 :         {
     202           0 :             if (!pb_readbyte(stream, &byte))
     203           0 :                 return false;
     204             :             
     205           0 :             if (bitpos >= 32)
     206           0 :             {
     207             :                 /* Note: The varint could have trailing 0x80 bytes, or 0xFF for negative. */
     208           0 :                 pb_byte_t sign_extension = (bitpos < 63) ? 0xFF : 0x01;
     209           0 :                 bool valid_extension = ((byte & 0x7F) == 0x00 ||
     210           0 :                          ((result >> 31) != 0 && byte == sign_extension));
     211             : 
     212           0 :                 if (bitpos >= 64 || !valid_extension)
     213           0 :                 {
     214           0 :                     PB_RETURN_ERROR(stream, "varint overflow");
     215           0 :                 }
     216           0 :             }
     217           0 :             else if (bitpos == 28)
     218           0 :             {
     219           0 :                 if ((byte & 0x70) != 0 && (byte & 0x78) != 0x78)
     220           0 :                 {
     221           0 :                     PB_RETURN_ERROR(stream, "varint overflow");
     222           0 :                 }
     223           0 :                 result |= (uint32_t)(byte & 0x0F) << bitpos;
     224           0 :             }
     225           0 :             else
     226           0 :             {
     227           0 :                 result |= (uint32_t)(byte & 0x7F) << bitpos;
     228           0 :             }
     229           0 :             bitpos = (uint_fast8_t)(bitpos + 7);
     230           0 :         } while (byte & 0x80);
     231           0 :    }
     232             :    
     233           0 :    *dest = result;
     234           0 :    return true;
     235           0 : }
     236             : 
     237             : bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)
     238           0 : {
     239           0 :     return pb_decode_varint32_eof(stream, dest, NULL);
     240           0 : }
     241             : 
     242             : #ifndef PB_WITHOUT_64BIT
     243             : bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest)
     244           0 : {
     245           0 :     pb_byte_t byte;
     246           0 :     uint_fast8_t bitpos = 0;
     247           0 :     uint64_t result = 0;
     248             :     
     249           0 :     do
     250           0 :     {
     251           0 :         if (!pb_readbyte(stream, &byte))
     252           0 :             return false;
     253             : 
     254           0 :         if (bitpos >= 63 && (byte & 0xFE) != 0)
     255           0 :             PB_RETURN_ERROR(stream, "varint overflow");
     256             : 
     257           0 :         result |= (uint64_t)(byte & 0x7F) << bitpos;
     258           0 :         bitpos = (uint_fast8_t)(bitpos + 7);
     259           0 :     } while (byte & 0x80);
     260             :     
     261           0 :     *dest = result;
     262           0 :     return true;
     263           0 : }
     264             : #endif
     265             : 
     266             : bool checkreturn pb_skip_varint(pb_istream_t *stream)
     267           0 : {
     268           0 :     pb_byte_t byte;
     269           0 :     do
     270           0 :     {
     271           0 :         if (!pb_read(stream, &byte, 1))
     272           0 :             return false;
     273           0 :     } while (byte & 0x80);
     274           0 :     return true;
     275           0 : }
     276             : 
     277             : bool checkreturn pb_skip_string(pb_istream_t *stream)
     278           0 : {
     279           0 :     uint32_t length;
     280           0 :     if (!pb_decode_varint32(stream, &length))
     281           0 :         return false;
     282             :     
     283           0 :     if ((size_t)length != length)
     284           0 :     {
     285           0 :         PB_RETURN_ERROR(stream, "size too large");
     286           0 :     }
     287             : 
     288           0 :     return pb_read(stream, NULL, (size_t)length);
     289           0 : }
     290             : 
     291             : bool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof)
     292           0 : {
     293           0 :     uint32_t temp;
     294           0 :     *eof = false;
     295           0 :     *wire_type = (pb_wire_type_t) 0;
     296           0 :     *tag = 0;
     297             :     
     298           0 :     if (!pb_decode_varint32_eof(stream, &temp, eof))
     299           0 :     {
     300           0 :         return false;
     301           0 :     }
     302             :     
     303           0 :     *tag = temp >> 3;
     304           0 :     *wire_type = (pb_wire_type_t)(temp & 7);
     305           0 :     return true;
     306           0 : }
     307             : 
     308             : bool checkreturn pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type)
     309           0 : {
     310           0 :     switch (wire_type)
     311           0 :     {
     312           0 :         case PB_WT_VARINT: return pb_skip_varint(stream);
     313           0 :         case PB_WT_64BIT: return pb_read(stream, NULL, 8);
     314           0 :         case PB_WT_STRING: return pb_skip_string(stream);
     315           0 :         case PB_WT_32BIT: return pb_read(stream, NULL, 4);
     316           0 :         default: PB_RETURN_ERROR(stream, "invalid wire_type");
     317           0 :     }
     318           0 : }
     319             : 
     320             : /* Read a raw value to buffer, for the purpose of passing it to callback as
     321             :  * a substream. Size is maximum size on call, and actual size on return.
     322             :  */
     323             : static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size)
     324           0 : {
     325           0 :     size_t max_size = *size;
     326           0 :     switch (wire_type)
     327           0 :     {
     328           0 :         case PB_WT_VARINT:
     329           0 :             *size = 0;
     330           0 :             do
     331           0 :             {
     332           0 :                 (*size)++;
     333           0 :                 if (*size > max_size)
     334           0 :                     PB_RETURN_ERROR(stream, "varint overflow");
     335             : 
     336           0 :                 if (!pb_read(stream, buf, 1))
     337           0 :                     return false;
     338           0 :             } while (*buf++ & 0x80);
     339           0 :             return true;
     340             :             
     341           0 :         case PB_WT_64BIT:
     342           0 :             *size = 8;
     343           0 :             return pb_read(stream, buf, 8);
     344             :         
     345           0 :         case PB_WT_32BIT:
     346           0 :             *size = 4;
     347           0 :             return pb_read(stream, buf, 4);
     348             :         
     349           0 :         case PB_WT_STRING:
     350             :             /* Calling read_raw_value with a PB_WT_STRING is an error.
     351             :              * Explicitly handle this case and fallthrough to default to avoid
     352             :              * compiler warnings.
     353             :              */
     354             : 
     355           0 :         default: PB_RETURN_ERROR(stream, "invalid wire_type");
     356           0 :     }
     357           0 : }
     358             : 
     359             : /* Decode string length from stream and return a substream with limited length.
     360             :  * Remember to close the substream using pb_close_string_substream().
     361             :  */
     362             : bool checkreturn pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream)
     363           0 : {
     364           0 :     uint32_t size;
     365           0 :     if (!pb_decode_varint32(stream, &size))
     366           0 :         return false;
     367             :     
     368           0 :     *substream = *stream;
     369           0 :     if (substream->bytes_left < size)
     370           0 :         PB_RETURN_ERROR(stream, "parent stream too short");
     371             :     
     372           0 :     substream->bytes_left = (size_t)size;
     373           0 :     stream->bytes_left -= (size_t)size;
     374           0 :     return true;
     375           0 : }
     376             : 
     377             : bool checkreturn pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream)
     378           0 : {
     379           0 :     if (substream->bytes_left) {
     380           0 :         if (!pb_read(substream, NULL, substream->bytes_left))
     381           0 :             return false;
     382           0 :     }
     383             : 
     384           0 :     stream->state = substream->state;
     385             : 
     386           0 : #ifndef PB_NO_ERRMSG
     387           0 :     stream->errmsg = substream->errmsg;
     388           0 : #endif
     389           0 :     return true;
     390           0 : }
     391             : 
     392             : /*************************
     393             :  * Decode a single field *
     394             :  *************************/
     395             : 
     396             : static bool checkreturn decode_basic_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field)
     397           0 : {
     398           0 :     switch (PB_LTYPE(field->type))
     399           0 :     {
     400           0 :         case PB_LTYPE_BOOL:
     401           0 :             if (wire_type != PB_WT_VARINT && wire_type != PB_WT_PACKED)
     402           0 :                 PB_RETURN_ERROR(stream, "wrong wire type");
     403             : 
     404           0 :             return pb_dec_bool(stream, field);
     405             : 
     406           0 :         case PB_LTYPE_VARINT:
     407           0 :         case PB_LTYPE_UVARINT:
     408           0 :         case PB_LTYPE_SVARINT:
     409           0 :             if (wire_type != PB_WT_VARINT && wire_type != PB_WT_PACKED)
     410           0 :                 PB_RETURN_ERROR(stream, "wrong wire type");
     411             : 
     412           0 :             return pb_dec_varint(stream, field);
     413             : 
     414           0 :         case PB_LTYPE_FIXED32:
     415           0 :             if (wire_type != PB_WT_32BIT && wire_type != PB_WT_PACKED)
     416           0 :                 PB_RETURN_ERROR(stream, "wrong wire type");
     417             : 
     418           0 :             return pb_decode_fixed32(stream, field->pData);
     419             : 
     420           0 :         case PB_LTYPE_FIXED64:
     421           0 :             if (wire_type != PB_WT_64BIT && wire_type != PB_WT_PACKED)
     422           0 :                 PB_RETURN_ERROR(stream, "wrong wire type");
     423             : 
     424             : #ifdef PB_CONVERT_DOUBLE_FLOAT
     425             :             if (field->data_size == sizeof(float))
     426             :             {
     427             :                 return pb_decode_double_as_float(stream, (float*)field->pData);
     428             :             }
     429             : #endif
     430             : 
     431             : #ifdef PB_WITHOUT_64BIT
     432             :             PB_RETURN_ERROR(stream, "invalid data_size");
     433             : #else
     434           0 :             return pb_decode_fixed64(stream, field->pData);
     435           0 : #endif
     436             : 
     437           0 :         case PB_LTYPE_BYTES:
     438           0 :             if (wire_type != PB_WT_STRING)
     439           0 :                 PB_RETURN_ERROR(stream, "wrong wire type");
     440             : 
     441           0 :             return pb_dec_bytes(stream, field);
     442             : 
     443           0 :         case PB_LTYPE_STRING:
     444           0 :             if (wire_type != PB_WT_STRING)
     445           0 :                 PB_RETURN_ERROR(stream, "wrong wire type");
     446             : 
     447           0 :             return pb_dec_string(stream, field);
     448             : 
     449           0 :         case PB_LTYPE_SUBMESSAGE:
     450           0 :         case PB_LTYPE_SUBMSG_W_CB:
     451           0 :             if (wire_type != PB_WT_STRING)
     452           0 :                 PB_RETURN_ERROR(stream, "wrong wire type");
     453             : 
     454           0 :             return pb_dec_submessage(stream, field);
     455             : 
     456           0 :         case PB_LTYPE_FIXED_LENGTH_BYTES:
     457           0 :             if (wire_type != PB_WT_STRING)
     458           0 :                 PB_RETURN_ERROR(stream, "wrong wire type");
     459             : 
     460           0 :             return pb_dec_fixed_length_bytes(stream, field);
     461             : 
     462           0 :         default:
     463           0 :             PB_RETURN_ERROR(stream, "invalid field type");
     464           0 :     }
     465           0 : }
     466             : 
     467             : static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field)
     468           0 : {
     469           0 :     switch (PB_HTYPE(field->type))
     470           0 :     {
     471           0 :         case PB_HTYPE_REQUIRED:
     472           0 :             return decode_basic_field(stream, wire_type, field);
     473             :             
     474           0 :         case PB_HTYPE_OPTIONAL:
     475           0 :             if (field->pSize != NULL)
     476           0 :                 *(bool*)field->pSize = true;
     477           0 :             return decode_basic_field(stream, wire_type, field);
     478             :     
     479           0 :         case PB_HTYPE_REPEATED:
     480           0 :             if (wire_type == PB_WT_STRING
     481           0 :                 && PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE)
     482           0 :             {
     483             :                 /* Packed array */
     484           0 :                 bool status = true;
     485           0 :                 pb_istream_t substream;
     486           0 :                 pb_size_t *size = (pb_size_t*)field->pSize;
     487           0 :                 field->pData = (char*)field->pField + field->data_size * (*size);
     488             : 
     489           0 :                 if (!pb_make_string_substream(stream, &substream))
     490           0 :                     return false;
     491             : 
     492           0 :                 while (substream.bytes_left > 0 && *size < field->array_size)
     493           0 :                 {
     494           0 :                     if (!decode_basic_field(&substream, PB_WT_PACKED, field))
     495           0 :                     {
     496           0 :                         status = false;
     497           0 :                         break;
     498           0 :                     }
     499           0 :                     (*size)++;
     500           0 :                     field->pData = (char*)field->pData + field->data_size;
     501           0 :                 }
     502             : 
     503           0 :                 if (substream.bytes_left != 0)
     504           0 :                     PB_RETURN_ERROR(stream, "array overflow");
     505           0 :                 if (!pb_close_string_substream(stream, &substream))
     506           0 :                     return false;
     507             : 
     508           0 :                 return status;
     509           0 :             }
     510           0 :             else
     511           0 :             {
     512             :                 /* Repeated field */
     513           0 :                 pb_size_t *size = (pb_size_t*)field->pSize;
     514           0 :                 field->pData = (char*)field->pField + field->data_size * (*size);
     515             : 
     516           0 :                 if ((*size)++ >= field->array_size)
     517           0 :                     PB_RETURN_ERROR(stream, "array overflow");
     518             : 
     519           0 :                 return decode_basic_field(stream, wire_type, field);
     520           0 :             }
     521             : 
     522           0 :         case PB_HTYPE_ONEOF:
     523           0 :             if (PB_LTYPE_IS_SUBMSG(field->type) &&
     524           0 :                 *(pb_size_t*)field->pSize != field->tag)
     525           0 :             {
     526             :                 /* We memset to zero so that any callbacks are set to NULL.
     527             :                  * This is because the callbacks might otherwise have values
     528             :                  * from some other union field.
     529             :                  * If callbacks are needed inside oneof field, use .proto
     530             :                  * option submsg_callback to have a separate callback function
     531             :                  * that can set the fields before submessage is decoded.
     532             :                  * pb_dec_submessage() will set any default values. */
     533           0 :                 memset(field->pData, 0, (size_t)field->data_size);
     534             : 
     535             :                 /* Set default values for the submessage fields. */
     536           0 :                 if (field->submsg_desc->default_value != NULL ||
     537           0 :                     field->submsg_desc->field_callback != NULL ||
     538           0 :                     field->submsg_desc->submsg_info[0] != NULL)
     539           0 :                 {
     540           0 :                     pb_field_iter_t submsg_iter;
     541           0 :                     if (pb_field_iter_begin(&submsg_iter, field->submsg_desc, field->pData))
     542           0 :                     {
     543           0 :                         if (!pb_message_set_to_defaults(&submsg_iter))
     544           0 :                             PB_RETURN_ERROR(stream, "failed to set defaults");
     545           0 :                     }
     546           0 :                 }
     547           0 :             }
     548           0 :             *(pb_size_t*)field->pSize = field->tag;
     549             : 
     550           0 :             return decode_basic_field(stream, wire_type, field);
     551             : 
     552           0 :         default:
     553           0 :             PB_RETURN_ERROR(stream, "invalid field type");
     554           0 :     }
     555           0 : }
     556             : 
     557             : #ifdef PB_ENABLE_MALLOC
     558             : /* Allocate storage for the field and store the pointer at iter->pData.
     559             :  * array_size is the number of entries to reserve in an array.
     560             :  * Zero size is not allowed, use pb_free() for releasing.
     561             :  */
     562             : static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size)
     563           0 : {    
     564           0 :     void *ptr = *(void**)pData;
     565             :     
     566           0 :     if (data_size == 0 || array_size == 0)
     567           0 :         PB_RETURN_ERROR(stream, "invalid size");
     568             :     
     569             : #ifdef __AVR__
     570             :     /* Workaround for AVR libc bug 53284: http://savannah.nongnu.org/bugs/?53284
     571             :      * Realloc to size of 1 byte can cause corruption of the malloc structures.
     572             :      */
     573             :     if (data_size == 1 && array_size == 1)
     574             :     {
     575             :         data_size = 2;
     576             :     }
     577             : #endif
     578             : 
     579             :     /* Check for multiplication overflows.
     580             :      * This code avoids the costly division if the sizes are small enough.
     581             :      * Multiplication is safe as long as only half of bits are set
     582             :      * in either multiplicand.
     583             :      */
     584           0 :     {
     585           0 :         const size_t check_limit = (size_t)1 << (sizeof(size_t) * 4);
     586           0 :         if (data_size >= check_limit || array_size >= check_limit)
     587           0 :         {
     588           0 :             const size_t size_max = (size_t)-1;
     589           0 :             if (size_max / array_size < data_size)
     590           0 :             {
     591           0 :                 PB_RETURN_ERROR(stream, "size too large");
     592           0 :             }
     593           0 :         }
     594           0 :     }
     595             :     
     596             :     /* Allocate new or expand previous allocation */
     597             :     /* Note: on failure the old pointer will remain in the structure,
     598             :      * the message must be freed by caller also on error return. */
     599           0 :     ptr = pb_realloc(ptr, array_size * data_size);
     600           0 :     if (ptr == NULL)
     601           0 :         PB_RETURN_ERROR(stream, "realloc failed");
     602             :     
     603           0 :     *(void**)pData = ptr;
     604           0 :     return true;
     605           0 : }
     606             : 
     607             : /* Clear a newly allocated item in case it contains a pointer, or is a submessage. */
     608             : static void initialize_pointer_field(void *pItem, pb_field_iter_t *field)
     609           0 : {
     610           0 :     if (PB_LTYPE(field->type) == PB_LTYPE_STRING ||
     611           0 :         PB_LTYPE(field->type) == PB_LTYPE_BYTES)
     612           0 :     {
     613           0 :         *(void**)pItem = NULL;
     614           0 :     }
     615           0 :     else if (PB_LTYPE_IS_SUBMSG(field->type))
     616           0 :     {
     617             :         /* We memset to zero so that any callbacks are set to NULL.
     618             :          * Default values will be set by pb_dec_submessage(). */
     619           0 :         memset(pItem, 0, field->data_size);
     620           0 :     }
     621           0 : }
     622             : #endif
     623             : 
     624             : static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field)
     625           0 : {
     626             : #ifndef PB_ENABLE_MALLOC
     627             :     PB_UNUSED(wire_type);
     628             :     PB_UNUSED(field);
     629             :     PB_RETURN_ERROR(stream, "no malloc support");
     630             : #else
     631           0 :     switch (PB_HTYPE(field->type))
     632           0 :     {
     633           0 :         case PB_HTYPE_REQUIRED:
     634           0 :         case PB_HTYPE_OPTIONAL:
     635           0 :         case PB_HTYPE_ONEOF:
     636           0 :             if (PB_LTYPE_IS_SUBMSG(field->type) && *(void**)field->pField != NULL)
     637           0 :             {
     638             :                 /* Duplicate field, have to release the old allocation first. */
     639             :                 /* FIXME: Does this work correctly for oneofs? */
     640           0 :                 pb_release_single_field(field);
     641           0 :             }
     642             :         
     643           0 :             if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF)
     644           0 :             {
     645           0 :                 *(pb_size_t*)field->pSize = field->tag;
     646           0 :             }
     647             : 
     648           0 :             if (PB_LTYPE(field->type) == PB_LTYPE_STRING ||
     649           0 :                 PB_LTYPE(field->type) == PB_LTYPE_BYTES)
     650           0 :             {
     651             :                 /* pb_dec_string and pb_dec_bytes handle allocation themselves */
     652           0 :                 field->pData = field->pField;
     653           0 :                 return decode_basic_field(stream, wire_type, field);
     654           0 :             }
     655           0 :             else
     656           0 :             {
     657           0 :                 if (!allocate_field(stream, field->pField, field->data_size, 1))
     658           0 :                     return false;
     659             :                 
     660           0 :                 field->pData = *(void**)field->pField;
     661           0 :                 initialize_pointer_field(field->pData, field);
     662           0 :                 return decode_basic_field(stream, wire_type, field);
     663           0 :             }
     664             :     
     665           0 :         case PB_HTYPE_REPEATED:
     666           0 :             if (wire_type == PB_WT_STRING
     667           0 :                 && PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE)
     668           0 :             {
     669             :                 /* Packed array, multiple items come in at once. */
     670           0 :                 bool status = true;
     671           0 :                 pb_size_t *size = (pb_size_t*)field->pSize;
     672           0 :                 size_t allocated_size = *size;
     673           0 :                 pb_istream_t substream;
     674             :                 
     675           0 :                 if (!pb_make_string_substream(stream, &substream))
     676           0 :                     return false;
     677             :                 
     678           0 :                 while (substream.bytes_left)
     679           0 :                 {
     680           0 :                     if (*size == PB_SIZE_MAX)
     681           0 :                     {
     682           0 : #ifndef PB_NO_ERRMSG
     683           0 :                         stream->errmsg = "too many array entries";
     684           0 : #endif
     685           0 :                         status = false;
     686           0 :                         break;
     687           0 :                     }
     688             : 
     689           0 :                     if ((size_t)*size + 1 > allocated_size)
     690           0 :                     {
     691             :                         /* Allocate more storage. This tries to guess the
     692             :                          * number of remaining entries. Round the division
     693             :                          * upwards. */
     694           0 :                         size_t remain = (substream.bytes_left - 1) / field->data_size + 1;
     695           0 :                         if (remain < PB_SIZE_MAX - allocated_size)
     696           0 :                             allocated_size += remain;
     697           0 :                         else
     698           0 :                             allocated_size += 1;
     699             :                         
     700           0 :                         if (!allocate_field(&substream, field->pField, field->data_size, allocated_size))
     701           0 :                         {
     702           0 :                             status = false;
     703           0 :                             break;
     704           0 :                         }
     705           0 :                     }
     706             : 
     707             :                     /* Decode the array entry */
     708           0 :                     field->pData = *(char**)field->pField + field->data_size * (*size);
     709           0 :                     if (field->pData == NULL)
     710           0 :                     {
     711             :                         /* Shouldn't happen, but satisfies static analyzers */
     712           0 :                         status = false;
     713           0 :                         break;
     714           0 :                     }
     715           0 :                     initialize_pointer_field(field->pData, field);
     716           0 :                     if (!decode_basic_field(&substream, PB_WT_PACKED, field))
     717           0 :                     {
     718           0 :                         status = false;
     719           0 :                         break;
     720           0 :                     }
     721             :                     
     722           0 :                     (*size)++;
     723           0 :                 }
     724           0 :                 if (!pb_close_string_substream(stream, &substream))
     725           0 :                     return false;
     726             :                 
     727           0 :                 return status;
     728           0 :             }
     729           0 :             else
     730           0 :             {
     731             :                 /* Normal repeated field, i.e. only one item at a time. */
     732           0 :                 pb_size_t *size = (pb_size_t*)field->pSize;
     733             : 
     734           0 :                 if (*size == PB_SIZE_MAX)
     735           0 :                     PB_RETURN_ERROR(stream, "too many array entries");
     736             :                 
     737           0 :                 if (!allocate_field(stream, field->pField, field->data_size, (size_t)(*size + 1)))
     738           0 :                     return false;
     739             :             
     740           0 :                 field->pData = *(char**)field->pField + field->data_size * (*size);
     741           0 :                 (*size)++;
     742           0 :                 initialize_pointer_field(field->pData, field);
     743           0 :                 return decode_basic_field(stream, wire_type, field);
     744           0 :             }
     745             : 
     746           0 :         default:
     747           0 :             PB_RETURN_ERROR(stream, "invalid field type");
     748           0 :     }
     749           0 : #endif
     750           0 : }
     751             : 
     752             : static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field)
     753           0 : {
     754           0 :     if (!field->descriptor->field_callback)
     755           0 :         return pb_skip_field(stream, wire_type);
     756             : 
     757           0 :     if (wire_type == PB_WT_STRING)
     758           0 :     {
     759           0 :         pb_istream_t substream;
     760           0 :         size_t prev_bytes_left;
     761             :         
     762           0 :         if (!pb_make_string_substream(stream, &substream))
     763           0 :             return false;
     764             :         
     765           0 :         do
     766           0 :         {
     767           0 :             prev_bytes_left = substream.bytes_left;
     768           0 :             if (!field->descriptor->field_callback(&substream, NULL, field))
     769           0 :             {
     770           0 :                 PB_SET_ERROR(stream, substream.errmsg ? substream.errmsg : "callback failed");
     771           0 :                 return false;
     772           0 :             }
     773           0 :         } while (substream.bytes_left > 0 && substream.bytes_left < prev_bytes_left);
     774             :         
     775           0 :         if (!pb_close_string_substream(stream, &substream))
     776           0 :             return false;
     777             : 
     778           0 :         return true;
     779           0 :     }
     780           0 :     else
     781           0 :     {
     782             :         /* Copy the single scalar value to stack.
     783             :          * This is required so that we can limit the stream length,
     784             :          * which in turn allows to use same callback for packed and
     785             :          * not-packed fields. */
     786           0 :         pb_istream_t substream;
     787           0 :         pb_byte_t buffer[10];
     788           0 :         size_t size = sizeof(buffer);
     789             :         
     790           0 :         if (!read_raw_value(stream, wire_type, buffer, &size))
     791           0 :             return false;
     792           0 :         substream = pb_istream_from_buffer(buffer, size);
     793             :         
     794           0 :         return field->descriptor->field_callback(&substream, NULL, field);
     795           0 :     }
     796           0 : }
     797             : 
     798             : static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field)
     799           0 : {
     800           0 : #ifdef PB_ENABLE_MALLOC
     801             :     /* When decoding an oneof field, check if there is old data that must be
     802             :      * released first. */
     803           0 :     if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF)
     804           0 :     {
     805           0 :         if (!pb_release_union_field(stream, field))
     806           0 :             return false;
     807           0 :     }
     808           0 : #endif
     809             : 
     810           0 :     switch (PB_ATYPE(field->type))
     811           0 :     {
     812           0 :         case PB_ATYPE_STATIC:
     813           0 :             return decode_static_field(stream, wire_type, field);
     814             :         
     815           0 :         case PB_ATYPE_POINTER:
     816           0 :             return decode_pointer_field(stream, wire_type, field);
     817             :         
     818           0 :         case PB_ATYPE_CALLBACK:
     819           0 :             return decode_callback_field(stream, wire_type, field);
     820             :         
     821           0 :         default:
     822           0 :             PB_RETURN_ERROR(stream, "invalid field type");
     823           0 :     }
     824           0 : }
     825             : 
     826             : /* Default handler for extension fields. Expects to have a pb_msgdesc_t
     827             :  * pointer in the extension->type->arg field, pointing to a message with
     828             :  * only one field in it.  */
     829             : static bool checkreturn default_extension_decoder(pb_istream_t *stream,
     830             :     pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type)
     831           0 : {
     832           0 :     pb_field_iter_t iter;
     833             : 
     834           0 :     if (!pb_field_iter_begin_extension(&iter, extension))
     835           0 :         PB_RETURN_ERROR(stream, "invalid extension");
     836             : 
     837           0 :     if (iter.tag != tag || !iter.message)
     838           0 :         return true;
     839             : 
     840           0 :     extension->found = true;
     841           0 :     return decode_field(stream, wire_type, &iter);
     842           0 : }
     843             : 
     844             : /* Try to decode an unknown field as an extension field. Tries each extension
     845             :  * decoder in turn, until one of them handles the field or loop ends. */
     846             : static bool checkreturn decode_extension(pb_istream_t *stream,
     847             :     uint32_t tag, pb_wire_type_t wire_type, pb_extension_t *extension)
     848           0 : {
     849           0 :     size_t pos = stream->bytes_left;
     850             :     
     851           0 :     while (extension != NULL && pos == stream->bytes_left)
     852           0 :     {
     853           0 :         bool status;
     854           0 :         if (extension->type->decode)
     855           0 :             status = extension->type->decode(stream, extension, tag, wire_type);
     856           0 :         else
     857           0 :             status = default_extension_decoder(stream, extension, tag, wire_type);
     858             : 
     859           0 :         if (!status)
     860           0 :             return false;
     861             :         
     862           0 :         extension = extension->next;
     863           0 :     }
     864             :     
     865           0 :     return true;
     866           0 : }
     867             : 
     868             : /* Initialize message fields to default values, recursively */
     869             : static bool pb_field_set_to_default(pb_field_iter_t *field)
     870           0 : {
     871           0 :     pb_type_t type;
     872           0 :     type = field->type;
     873             : 
     874           0 :     if (PB_LTYPE(type) == PB_LTYPE_EXTENSION)
     875           0 :     {
     876           0 :         pb_extension_t *ext = *(pb_extension_t* const *)field->pData;
     877           0 :         while (ext != NULL)
     878           0 :         {
     879           0 :             pb_field_iter_t ext_iter;
     880           0 :             if (pb_field_iter_begin_extension(&ext_iter, ext))
     881           0 :             {
     882           0 :                 ext->found = false;
     883           0 :                 if (!pb_message_set_to_defaults(&ext_iter))
     884           0 :                     return false;
     885           0 :             }
     886           0 :             ext = ext->next;
     887           0 :         }
     888           0 :     }
     889           0 :     else if (PB_ATYPE(type) == PB_ATYPE_STATIC)
     890           0 :     {
     891           0 :         bool init_data = true;
     892           0 :         if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && field->pSize != NULL)
     893           0 :         {
     894             :             /* Set has_field to false. Still initialize the optional field
     895             :              * itself also. */
     896           0 :             *(bool*)field->pSize = false;
     897           0 :         }
     898           0 :         else if (PB_HTYPE(type) == PB_HTYPE_REPEATED ||
     899           0 :                  PB_HTYPE(type) == PB_HTYPE_ONEOF)
     900           0 :         {
     901             :             /* REPEATED: Set array count to 0, no need to initialize contents.
     902             :                ONEOF: Set which_field to 0. */
     903           0 :             *(pb_size_t*)field->pSize = 0;
     904           0 :             init_data = false;
     905           0 :         }
     906             : 
     907           0 :         if (init_data)
     908           0 :         {
     909           0 :             if (PB_LTYPE_IS_SUBMSG(field->type) &&
     910           0 :                 (field->submsg_desc->default_value != NULL ||
     911           0 :                  field->submsg_desc->field_callback != NULL ||
     912           0 :                  field->submsg_desc->submsg_info[0] != NULL))
     913           0 :             {
     914             :                 /* Initialize submessage to defaults.
     915             :                  * Only needed if it has default values
     916             :                  * or callback/submessage fields. */
     917           0 :                 pb_field_iter_t submsg_iter;
     918           0 :                 if (pb_field_iter_begin(&submsg_iter, field->submsg_desc, field->pData))
     919           0 :                 {
     920           0 :                     if (!pb_message_set_to_defaults(&submsg_iter))
     921           0 :                         return false;
     922           0 :                 }
     923           0 :             }
     924           0 :             else
     925           0 :             {
     926             :                 /* Initialize to zeros */
     927           0 :                 memset(field->pData, 0, (size_t)field->data_size);
     928           0 :             }
     929           0 :         }
     930           0 :     }
     931           0 :     else if (PB_ATYPE(type) == PB_ATYPE_POINTER)
     932           0 :     {
     933             :         /* Initialize the pointer to NULL. */
     934           0 :         *(void**)field->pField = NULL;
     935             : 
     936             :         /* Initialize array count to 0. */
     937           0 :         if (PB_HTYPE(type) == PB_HTYPE_REPEATED ||
     938           0 :             PB_HTYPE(type) == PB_HTYPE_ONEOF)
     939           0 :         {
     940           0 :             *(pb_size_t*)field->pSize = 0;
     941           0 :         }
     942           0 :     }
     943           0 :     else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK)
     944           0 :     {
     945             :         /* Don't overwrite callback */
     946           0 :     }
     947             : 
     948           0 :     return true;
     949           0 : }
     950             : 
     951             : static bool pb_message_set_to_defaults(pb_field_iter_t *iter)
     952           0 : {
     953           0 :     pb_istream_t defstream = PB_ISTREAM_EMPTY;
     954           0 :     uint32_t tag = 0;
     955           0 :     pb_wire_type_t wire_type = PB_WT_VARINT;
     956           0 :     bool eof;
     957             : 
     958           0 :     if (iter->descriptor->default_value)
     959           0 :     {
     960           0 :         defstream = pb_istream_from_buffer(iter->descriptor->default_value, (size_t)-1);
     961           0 :         if (!pb_decode_tag(&defstream, &wire_type, &tag, &eof))
     962           0 :             return false;
     963           0 :     }
     964             : 
     965           0 :     do
     966           0 :     {
     967           0 :         if (!pb_field_set_to_default(iter))
     968           0 :             return false;
     969             : 
     970           0 :         if (tag != 0 && iter->tag == tag)
     971           0 :         {
     972             :             /* We have a default value for this field in the defstream */
     973           0 :             if (!decode_field(&defstream, wire_type, iter))
     974           0 :                 return false;
     975           0 :             if (!pb_decode_tag(&defstream, &wire_type, &tag, &eof))
     976           0 :                 return false;
     977             : 
     978           0 :             if (iter->pSize)
     979           0 :                 *(bool*)iter->pSize = false;
     980           0 :         }
     981           0 :     } while (pb_field_iter_next(iter));
     982             : 
     983           0 :     return true;
     984           0 : }
     985             : 
     986             : /*********************
     987             :  * Decode all fields *
     988             :  *********************/
     989             : 
     990             : static bool checkreturn pb_decode_inner(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct, unsigned int flags)
     991           0 : {
     992           0 :     uint32_t extension_range_start = 0;
     993           0 :     pb_extension_t *extensions = NULL;
     994             : 
     995             :     /* 'fixed_count_field' and 'fixed_count_size' track position of a repeated fixed
     996             :      * count field. This can only handle _one_ repeated fixed count field that
     997             :      * is unpacked and unordered among other (non repeated fixed count) fields.
     998             :      */
     999           0 :     pb_size_t fixed_count_field = PB_SIZE_MAX;
    1000           0 :     pb_size_t fixed_count_size = 0;
    1001           0 :     pb_size_t fixed_count_total_size = 0;
    1002             : 
    1003           0 :     pb_fields_seen_t fields_seen = {{0, 0}};
    1004           0 :     const uint32_t allbits = ~(uint32_t)0;
    1005           0 :     pb_field_iter_t iter;
    1006             : 
    1007           0 :     if (pb_field_iter_begin(&iter, fields, dest_struct))
    1008           0 :     {
    1009           0 :         if ((flags & PB_DECODE_NOINIT) == 0)
    1010           0 :         {
    1011           0 :             if (!pb_message_set_to_defaults(&iter))
    1012           0 :                 PB_RETURN_ERROR(stream, "failed to set defaults");
    1013           0 :         }
    1014           0 :     }
    1015             : 
    1016           0 :     while (stream->bytes_left)
    1017           0 :     {
    1018           0 :         uint32_t tag;
    1019           0 :         pb_wire_type_t wire_type;
    1020           0 :         bool eof;
    1021             : 
    1022           0 :         if (!pb_decode_tag(stream, &wire_type, &tag, &eof))
    1023           0 :         {
    1024           0 :             if (eof)
    1025           0 :                 break;
    1026           0 :             else
    1027           0 :                 return false;
    1028           0 :         }
    1029             : 
    1030           0 :         if (tag == 0)
    1031           0 :         {
    1032           0 :           if (flags & PB_DECODE_NULLTERMINATED)
    1033           0 :           {
    1034           0 :             break;
    1035           0 :           }
    1036           0 :           else
    1037           0 :           {
    1038           0 :             PB_RETURN_ERROR(stream, "zero tag");
    1039           0 :           }
    1040           0 :         }
    1041             : 
    1042           0 :         if (!pb_field_iter_find(&iter, tag) || PB_LTYPE(iter.type) == PB_LTYPE_EXTENSION)
    1043           0 :         {
    1044             :             /* No match found, check if it matches an extension. */
    1045           0 :             if (extension_range_start == 0)
    1046           0 :             {
    1047           0 :                 if (pb_field_iter_find_extension(&iter))
    1048           0 :                 {
    1049           0 :                     extensions = *(pb_extension_t* const *)iter.pData;
    1050           0 :                     extension_range_start = iter.tag;
    1051           0 :                 }
    1052             : 
    1053           0 :                 if (!extensions)
    1054           0 :                 {
    1055           0 :                     extension_range_start = (uint32_t)-1;
    1056           0 :                 }
    1057           0 :             }
    1058             : 
    1059           0 :             if (tag >= extension_range_start)
    1060           0 :             {
    1061           0 :                 size_t pos = stream->bytes_left;
    1062             : 
    1063           0 :                 if (!decode_extension(stream, tag, wire_type, extensions))
    1064           0 :                     return false;
    1065             : 
    1066           0 :                 if (pos != stream->bytes_left)
    1067           0 :                 {
    1068             :                     /* The field was handled */
    1069           0 :                     continue;
    1070           0 :                 }
    1071           0 :             }
    1072             : 
    1073             :             /* No match found, skip data */
    1074           0 :             if (!pb_skip_field(stream, wire_type))
    1075           0 :                 return false;
    1076           0 :             continue;
    1077           0 :         }
    1078             : 
    1079             :         /* If a repeated fixed count field was found, get size from
    1080             :          * 'fixed_count_field' as there is no counter contained in the struct.
    1081             :          */
    1082           0 :         if (PB_HTYPE(iter.type) == PB_HTYPE_REPEATED && iter.pSize == &iter.array_size)
    1083           0 :         {
    1084           0 :             if (fixed_count_field != iter.index) {
    1085             :                 /* If the new fixed count field does not match the previous one,
    1086             :                  * check that the previous one is NULL or that it finished
    1087             :                  * receiving all the expected data.
    1088             :                  */
    1089           0 :                 if (fixed_count_field != PB_SIZE_MAX &&
    1090           0 :                     fixed_count_size != fixed_count_total_size)
    1091           0 :                 {
    1092           0 :                     PB_RETURN_ERROR(stream, "wrong size for fixed count field");
    1093           0 :                 }
    1094             : 
    1095           0 :                 fixed_count_field = iter.index;
    1096           0 :                 fixed_count_size = 0;
    1097           0 :                 fixed_count_total_size = iter.array_size;
    1098           0 :             }
    1099             : 
    1100           0 :             iter.pSize = &fixed_count_size;
    1101           0 :         }
    1102             : 
    1103           0 :         if (PB_HTYPE(iter.type) == PB_HTYPE_REQUIRED
    1104           0 :             && iter.required_field_index < PB_MAX_REQUIRED_FIELDS)
    1105           0 :         {
    1106           0 :             uint32_t tmp = ((uint32_t)1 << (iter.required_field_index & 31));
    1107           0 :             fields_seen.bitfield[iter.required_field_index >> 5] |= tmp;
    1108           0 :         }
    1109             : 
    1110           0 :         if (!decode_field(stream, wire_type, &iter))
    1111           0 :             return false;
    1112           0 :     }
    1113             : 
    1114             :     /* Check that all elements of the last decoded fixed count field were present. */
    1115           0 :     if (fixed_count_field != PB_SIZE_MAX &&
    1116           0 :         fixed_count_size != fixed_count_total_size)
    1117           0 :     {
    1118           0 :         PB_RETURN_ERROR(stream, "wrong size for fixed count field");
    1119           0 :     }
    1120             : 
    1121             :     /* Check that all required fields were present. */
    1122           0 :     {
    1123           0 :         pb_size_t req_field_count = iter.descriptor->required_field_count;
    1124             : 
    1125           0 :         if (req_field_count > 0)
    1126           0 :         {
    1127           0 :             pb_size_t i;
    1128             : 
    1129           0 :             if (req_field_count > PB_MAX_REQUIRED_FIELDS)
    1130           0 :                 req_field_count = PB_MAX_REQUIRED_FIELDS;
    1131             : 
    1132             :             /* Check the whole words */
    1133           0 :             for (i = 0; i < (req_field_count >> 5); i++)
    1134           0 :             {
    1135           0 :                 if (fields_seen.bitfield[i] != allbits)
    1136           0 :                     PB_RETURN_ERROR(stream, "missing required field");
    1137           0 :             }
    1138             : 
    1139             :             /* Check the remaining bits (if any) */
    1140           0 :             if ((req_field_count & 31) != 0)
    1141           0 :             {
    1142           0 :                 if (fields_seen.bitfield[req_field_count >> 5] !=
    1143           0 :                     (allbits >> (uint_least8_t)(32 - (req_field_count & 31))))
    1144           0 :                 {
    1145           0 :                     PB_RETURN_ERROR(stream, "missing required field");
    1146           0 :                 }
    1147           0 :             }
    1148           0 :         }
    1149           0 :     }
    1150             : 
    1151           0 :     return true;
    1152           0 : }
    1153             : 
    1154             : bool checkreturn pb_decode_ex(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct, unsigned int flags)
    1155           0 : {
    1156           0 :     bool status;
    1157             : 
    1158           0 :     if ((flags & PB_DECODE_DELIMITED) == 0)
    1159           0 :     {
    1160           0 :       status = pb_decode_inner(stream, fields, dest_struct, flags);
    1161           0 :     }
    1162           0 :     else
    1163           0 :     {
    1164           0 :       pb_istream_t substream;
    1165           0 :       if (!pb_make_string_substream(stream, &substream))
    1166           0 :         return false;
    1167             : 
    1168           0 :       status = pb_decode_inner(&substream, fields, dest_struct, flags);
    1169             : 
    1170           0 :       if (!pb_close_string_substream(stream, &substream))
    1171           0 :         status = false;
    1172           0 :     }
    1173             :     
    1174           0 : #ifdef PB_ENABLE_MALLOC
    1175           0 :     if (!status)
    1176           0 :         pb_release(fields, dest_struct);
    1177           0 : #endif
    1178             :     
    1179           0 :     return status;
    1180           0 : }
    1181             : 
    1182             : bool checkreturn pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct)
    1183           0 : {
    1184           0 :     bool status;
    1185             : 
    1186           0 :     status = pb_decode_inner(stream, fields, dest_struct, 0);
    1187             : 
    1188           0 : #ifdef PB_ENABLE_MALLOC
    1189           0 :     if (!status)
    1190           0 :         pb_release(fields, dest_struct);
    1191           0 : #endif
    1192             : 
    1193           0 :     return status;
    1194           0 : }
    1195             : 
    1196             : #ifdef PB_ENABLE_MALLOC
    1197             : /* Given an oneof field, if there has already been a field inside this oneof,
    1198             :  * release it before overwriting with a different one. */
    1199             : static bool pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *field)
    1200           0 : {
    1201           0 :     pb_field_iter_t old_field = *field;
    1202           0 :     pb_size_t old_tag = *(pb_size_t*)field->pSize; /* Previous which_ value */
    1203           0 :     pb_size_t new_tag = field->tag; /* New which_ value */
    1204             : 
    1205           0 :     if (old_tag == 0)
    1206           0 :         return true; /* Ok, no old data in union */
    1207             : 
    1208           0 :     if (old_tag == new_tag)
    1209           0 :         return true; /* Ok, old data is of same type => merge */
    1210             : 
    1211             :     /* Release old data. The find can fail if the message struct contains
    1212             :      * invalid data. */
    1213           0 :     if (!pb_field_iter_find(&old_field, old_tag))
    1214           0 :         PB_RETURN_ERROR(stream, "invalid union tag");
    1215             : 
    1216           0 :     pb_release_single_field(&old_field);
    1217             : 
    1218           0 :     if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
    1219           0 :     {
    1220             :         /* Initialize the pointer to NULL to make sure it is valid
    1221             :          * even in case of error return. */
    1222           0 :         *(void**)field->pField = NULL;
    1223           0 :         field->pData = NULL;
    1224           0 :     }
    1225             : 
    1226           0 :     return true;
    1227           0 : }
    1228             : 
    1229             : static void pb_release_single_field(pb_field_iter_t *field)
    1230           0 : {
    1231           0 :     pb_type_t type;
    1232           0 :     type = field->type;
    1233             : 
    1234           0 :     if (PB_HTYPE(type) == PB_HTYPE_ONEOF)
    1235           0 :     {
    1236           0 :         if (*(pb_size_t*)field->pSize != field->tag)
    1237           0 :             return; /* This is not the current field in the union */
    1238           0 :     }
    1239             : 
    1240             :     /* Release anything contained inside an extension or submsg.
    1241             :      * This has to be done even if the submsg itself is statically
    1242             :      * allocated. */
    1243           0 :     if (PB_LTYPE(type) == PB_LTYPE_EXTENSION)
    1244           0 :     {
    1245             :         /* Release fields from all extensions in the linked list */
    1246           0 :         pb_extension_t *ext = *(pb_extension_t**)field->pData;
    1247           0 :         while (ext != NULL)
    1248           0 :         {
    1249           0 :             pb_field_iter_t ext_iter;
    1250           0 :             if (pb_field_iter_begin_extension(&ext_iter, ext))
    1251           0 :             {
    1252           0 :                 pb_release_single_field(&ext_iter);
    1253           0 :             }
    1254           0 :             ext = ext->next;
    1255           0 :         }
    1256           0 :     }
    1257           0 :     else if (PB_LTYPE_IS_SUBMSG(type) && PB_ATYPE(type) != PB_ATYPE_CALLBACK)
    1258           0 :     {
    1259             :         /* Release fields in submessage or submsg array */
    1260           0 :         pb_size_t count = 1;
    1261             :         
    1262           0 :         if (PB_ATYPE(type) == PB_ATYPE_POINTER)
    1263           0 :         {
    1264           0 :             field->pData = *(void**)field->pField;
    1265           0 :         }
    1266           0 :         else
    1267           0 :         {
    1268           0 :             field->pData = field->pField;
    1269           0 :         }
    1270             :         
    1271           0 :         if (PB_HTYPE(type) == PB_HTYPE_REPEATED)
    1272           0 :         {
    1273           0 :             count = *(pb_size_t*)field->pSize;
    1274             : 
    1275           0 :             if (PB_ATYPE(type) == PB_ATYPE_STATIC && count > field->array_size)
    1276           0 :             {
    1277             :                 /* Protect against corrupted _count fields */
    1278           0 :                 count = field->array_size;
    1279           0 :             }
    1280           0 :         }
    1281             :         
    1282           0 :         if (field->pData)
    1283           0 :         {
    1284           0 :             for (; count > 0; count--)
    1285           0 :             {
    1286           0 :                 pb_release(field->submsg_desc, field->pData);
    1287           0 :                 field->pData = (char*)field->pData + field->data_size;
    1288           0 :             }
    1289           0 :         }
    1290           0 :     }
    1291             :     
    1292           0 :     if (PB_ATYPE(type) == PB_ATYPE_POINTER)
    1293           0 :     {
    1294           0 :         if (PB_HTYPE(type) == PB_HTYPE_REPEATED &&
    1295           0 :             (PB_LTYPE(type) == PB_LTYPE_STRING ||
    1296           0 :              PB_LTYPE(type) == PB_LTYPE_BYTES))
    1297           0 :         {
    1298             :             /* Release entries in repeated string or bytes array */
    1299           0 :             void **pItem = *(void***)field->pField;
    1300           0 :             pb_size_t count = *(pb_size_t*)field->pSize;
    1301           0 :             for (; count > 0; count--)
    1302           0 :             {
    1303           0 :                 pb_free(*pItem);
    1304           0 :                 *pItem++ = NULL;
    1305           0 :             }
    1306           0 :         }
    1307             :         
    1308           0 :         if (PB_HTYPE(type) == PB_HTYPE_REPEATED)
    1309           0 :         {
    1310             :             /* We are going to release the array, so set the size to 0 */
    1311           0 :             *(pb_size_t*)field->pSize = 0;
    1312           0 :         }
    1313             :         
    1314             :         /* Release main pointer */
    1315           0 :         pb_free(*(void**)field->pField);
    1316           0 :         *(void**)field->pField = NULL;
    1317           0 :     }
    1318           0 : }
    1319             : 
    1320             : void pb_release(const pb_msgdesc_t *fields, void *dest_struct)
    1321           0 : {
    1322           0 :     pb_field_iter_t iter;
    1323             :     
    1324           0 :     if (!dest_struct)
    1325           0 :         return; /* Ignore NULL pointers, similar to free() */
    1326             : 
    1327           0 :     if (!pb_field_iter_begin(&iter, fields, dest_struct))
    1328           0 :         return; /* Empty message type */
    1329             :     
    1330           0 :     do
    1331           0 :     {
    1332           0 :         pb_release_single_field(&iter);
    1333           0 :     } while (pb_field_iter_next(&iter));
    1334           0 : }
    1335             : #else
    1336             : void pb_release(const pb_msgdesc_t *fields, void *dest_struct)
    1337             : {
    1338             :     /* Nothing to release without PB_ENABLE_MALLOC. */
    1339             :     PB_UNUSED(fields);
    1340             :     PB_UNUSED(dest_struct);
    1341             : }
    1342             : #endif
    1343             : 
    1344             : /* Field decoders */
    1345             : 
    1346             : bool pb_decode_bool(pb_istream_t *stream, bool *dest)
    1347           0 : {
    1348           0 :     uint32_t value;
    1349           0 :     if (!pb_decode_varint32(stream, &value))
    1350           0 :         return false;
    1351             : 
    1352           0 :     *(bool*)dest = (value != 0);
    1353           0 :     return true;
    1354           0 : }
    1355             : 
    1356             : bool pb_decode_svarint(pb_istream_t *stream, pb_int64_t *dest)
    1357           0 : {
    1358           0 :     pb_uint64_t value;
    1359           0 :     if (!pb_decode_varint(stream, &value))
    1360           0 :         return false;
    1361             :     
    1362           0 :     if (value & 1)
    1363           0 :         *dest = (pb_int64_t)(~(value >> 1));
    1364           0 :     else
    1365           0 :         *dest = (pb_int64_t)(value >> 1);
    1366             :     
    1367           0 :     return true;
    1368           0 : }
    1369             : 
    1370             : bool pb_decode_fixed32(pb_istream_t *stream, void *dest)
    1371           0 : {
    1372           0 :     union {
    1373           0 :         uint32_t fixed32;
    1374           0 :         pb_byte_t bytes[4];
    1375           0 :     } u;
    1376             : 
    1377           0 :     if (!pb_read(stream, u.bytes, 4))
    1378           0 :         return false;
    1379             : 
    1380           0 : #if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1
    1381             :     /* fast path - if we know that we're on little endian, assign directly */
    1382           0 :     *(uint32_t*)dest = u.fixed32;
    1383             : #else
    1384             :     *(uint32_t*)dest = ((uint32_t)u.bytes[0] << 0) |
    1385             :                        ((uint32_t)u.bytes[1] << 8) |
    1386             :                        ((uint32_t)u.bytes[2] << 16) |
    1387             :                        ((uint32_t)u.bytes[3] << 24);
    1388             : #endif
    1389           0 :     return true;
    1390           0 : }
    1391             : 
    1392             : #ifndef PB_WITHOUT_64BIT
    1393             : bool pb_decode_fixed64(pb_istream_t *stream, void *dest)
    1394           0 : {
    1395           0 :     union {
    1396           0 :         uint64_t fixed64;
    1397           0 :         pb_byte_t bytes[8];
    1398           0 :     } u;
    1399             : 
    1400           0 :     if (!pb_read(stream, u.bytes, 8))
    1401           0 :         return false;
    1402             : 
    1403           0 : #if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1
    1404             :     /* fast path - if we know that we're on little endian, assign directly */
    1405           0 :     *(uint64_t*)dest = u.fixed64;
    1406             : #else
    1407             :     *(uint64_t*)dest = ((uint64_t)u.bytes[0] << 0) |
    1408             :                        ((uint64_t)u.bytes[1] << 8) |
    1409             :                        ((uint64_t)u.bytes[2] << 16) |
    1410             :                        ((uint64_t)u.bytes[3] << 24) |
    1411             :                        ((uint64_t)u.bytes[4] << 32) |
    1412             :                        ((uint64_t)u.bytes[5] << 40) |
    1413             :                        ((uint64_t)u.bytes[6] << 48) |
    1414             :                        ((uint64_t)u.bytes[7] << 56);
    1415             : #endif
    1416           0 :     return true;
    1417           0 : }
    1418             : #endif
    1419             : 
    1420             : static bool checkreturn pb_dec_bool(pb_istream_t *stream, const pb_field_iter_t *field)
    1421           0 : {
    1422           0 :     return pb_decode_bool(stream, (bool*)field->pData);
    1423           0 : }
    1424             : 
    1425             : static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_iter_t *field)
    1426           0 : {
    1427           0 :     if (PB_LTYPE(field->type) == PB_LTYPE_UVARINT)
    1428           0 :     {
    1429           0 :         pb_uint64_t value, clamped;
    1430           0 :         if (!pb_decode_varint(stream, &value))
    1431           0 :             return false;
    1432             : 
    1433             :         /* Cast to the proper field size, while checking for overflows */
    1434           0 :         if (field->data_size == sizeof(pb_uint64_t))
    1435           0 :             clamped = *(pb_uint64_t*)field->pData = value;
    1436           0 :         else if (field->data_size == sizeof(uint32_t))
    1437           0 :             clamped = *(uint32_t*)field->pData = (uint32_t)value;
    1438           0 :         else if (field->data_size == sizeof(uint_least16_t))
    1439           0 :             clamped = *(uint_least16_t*)field->pData = (uint_least16_t)value;
    1440           0 :         else if (field->data_size == sizeof(uint_least8_t))
    1441           0 :             clamped = *(uint_least8_t*)field->pData = (uint_least8_t)value;
    1442           0 :         else
    1443           0 :             PB_RETURN_ERROR(stream, "invalid data_size");
    1444             : 
    1445           0 :         if (clamped != value)
    1446           0 :             PB_RETURN_ERROR(stream, "integer too large");
    1447             : 
    1448           0 :         return true;
    1449           0 :     }
    1450           0 :     else
    1451           0 :     {
    1452           0 :         pb_uint64_t value;
    1453           0 :         pb_int64_t svalue;
    1454           0 :         pb_int64_t clamped;
    1455             : 
    1456           0 :         if (PB_LTYPE(field->type) == PB_LTYPE_SVARINT)
    1457           0 :         {
    1458           0 :             if (!pb_decode_svarint(stream, &svalue))
    1459           0 :                 return false;
    1460           0 :         }
    1461           0 :         else
    1462           0 :         {
    1463           0 :             if (!pb_decode_varint(stream, &value))
    1464           0 :                 return false;
    1465             : 
    1466             :             /* See issue 97: Google's C++ protobuf allows negative varint values to
    1467             :             * be cast as int32_t, instead of the int64_t that should be used when
    1468             :             * encoding. Nanopb versions before 0.2.5 had a bug in encoding. In order to
    1469             :             * not break decoding of such messages, we cast <=32 bit fields to
    1470             :             * int32_t first to get the sign correct.
    1471             :             */
    1472           0 :             if (field->data_size == sizeof(pb_int64_t))
    1473           0 :                 svalue = (pb_int64_t)value;
    1474           0 :             else
    1475           0 :                 svalue = (int32_t)value;
    1476           0 :         }
    1477             : 
    1478             :         /* Cast to the proper field size, while checking for overflows */
    1479           0 :         if (field->data_size == sizeof(pb_int64_t))
    1480           0 :             clamped = *(pb_int64_t*)field->pData = svalue;
    1481           0 :         else if (field->data_size == sizeof(int32_t))
    1482           0 :             clamped = *(int32_t*)field->pData = (int32_t)svalue;
    1483           0 :         else if (field->data_size == sizeof(int_least16_t))
    1484           0 :             clamped = *(int_least16_t*)field->pData = (int_least16_t)svalue;
    1485           0 :         else if (field->data_size == sizeof(int_least8_t))
    1486           0 :             clamped = *(int_least8_t*)field->pData = (int_least8_t)svalue;
    1487           0 :         else
    1488           0 :             PB_RETURN_ERROR(stream, "invalid data_size");
    1489             : 
    1490           0 :         if (clamped != svalue)
    1491           0 :             PB_RETURN_ERROR(stream, "integer too large");
    1492             : 
    1493           0 :         return true;
    1494           0 :     }
    1495           0 : }
    1496             : 
    1497             : static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_iter_t *field)
    1498           0 : {
    1499           0 :     uint32_t size;
    1500           0 :     size_t alloc_size;
    1501           0 :     pb_bytes_array_t *dest;
    1502             :     
    1503           0 :     if (!pb_decode_varint32(stream, &size))
    1504           0 :         return false;
    1505             :     
    1506           0 :     if (size > PB_SIZE_MAX)
    1507           0 :         PB_RETURN_ERROR(stream, "bytes overflow");
    1508             :     
    1509           0 :     alloc_size = PB_BYTES_ARRAY_T_ALLOCSIZE(size);
    1510           0 :     if (size > alloc_size)
    1511           0 :         PB_RETURN_ERROR(stream, "size too large");
    1512             :     
    1513           0 :     if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
    1514           0 :     {
    1515             : #ifndef PB_ENABLE_MALLOC
    1516             :         PB_RETURN_ERROR(stream, "no malloc support");
    1517             : #else
    1518           0 :         if (stream->bytes_left < size)
    1519           0 :             PB_RETURN_ERROR(stream, "end-of-stream");
    1520             : 
    1521           0 :         if (!allocate_field(stream, field->pData, alloc_size, 1))
    1522           0 :             return false;
    1523           0 :         dest = *(pb_bytes_array_t**)field->pData;
    1524           0 : #endif
    1525           0 :     }
    1526           0 :     else
    1527           0 :     {
    1528           0 :         if (alloc_size > field->data_size)
    1529           0 :             PB_RETURN_ERROR(stream, "bytes overflow");
    1530           0 :         dest = (pb_bytes_array_t*)field->pData;
    1531           0 :     }
    1532             : 
    1533           0 :     dest->size = (pb_size_t)size;
    1534           0 :     return pb_read(stream, dest->bytes, (size_t)size);
    1535           0 : }
    1536             : 
    1537             : static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_iter_t *field)
    1538           0 : {
    1539           0 :     uint32_t size;
    1540           0 :     size_t alloc_size;
    1541           0 :     pb_byte_t *dest = (pb_byte_t*)field->pData;
    1542             : 
    1543           0 :     if (!pb_decode_varint32(stream, &size))
    1544           0 :         return false;
    1545             : 
    1546           0 :     if (size == (uint32_t)-1)
    1547           0 :         PB_RETURN_ERROR(stream, "size too large");
    1548             : 
    1549             :     /* Space for null terminator */
    1550           0 :     alloc_size = (size_t)(size + 1);
    1551             : 
    1552           0 :     if (alloc_size < size)
    1553           0 :         PB_RETURN_ERROR(stream, "size too large");
    1554             : 
    1555           0 :     if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
    1556           0 :     {
    1557             : #ifndef PB_ENABLE_MALLOC
    1558             :         PB_RETURN_ERROR(stream, "no malloc support");
    1559             : #else
    1560           0 :         if (stream->bytes_left < size)
    1561           0 :             PB_RETURN_ERROR(stream, "end-of-stream");
    1562             : 
    1563           0 :         if (!allocate_field(stream, field->pData, alloc_size, 1))
    1564           0 :             return false;
    1565           0 :         dest = *(pb_byte_t**)field->pData;
    1566           0 : #endif
    1567           0 :     }
    1568           0 :     else
    1569           0 :     {
    1570           0 :         if (alloc_size > field->data_size)
    1571           0 :             PB_RETURN_ERROR(stream, "string overflow");
    1572           0 :     }
    1573             :     
    1574           0 :     dest[size] = 0;
    1575             : 
    1576           0 :     if (!pb_read(stream, dest, (size_t)size))
    1577           0 :         return false;
    1578             : 
    1579             : #ifdef PB_VALIDATE_UTF8
    1580             :     if (!pb_validate_utf8((const char*)dest))
    1581             :         PB_RETURN_ERROR(stream, "invalid utf8");
    1582             : #endif
    1583             : 
    1584           0 :     return true;
    1585           0 : }
    1586             : 
    1587             : static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_iter_t *field)
    1588           0 : {
    1589           0 :     bool status = true;
    1590           0 :     bool submsg_consumed = false;
    1591           0 :     pb_istream_t substream;
    1592             : 
    1593           0 :     if (!pb_make_string_substream(stream, &substream))
    1594           0 :         return false;
    1595             :     
    1596           0 :     if (field->submsg_desc == NULL)
    1597           0 :         PB_RETURN_ERROR(stream, "invalid field descriptor");
    1598             :     
    1599             :     /* Submessages can have a separate message-level callback that is called
    1600             :      * before decoding the message. Typically it is used to set callback fields
    1601             :      * inside oneofs. */
    1602           0 :     if (PB_LTYPE(field->type) == PB_LTYPE_SUBMSG_W_CB && field->pSize != NULL)
    1603           0 :     {
    1604             :         /* Message callback is stored right before pSize. */
    1605           0 :         pb_callback_t *callback = (pb_callback_t*)field->pSize - 1;
    1606           0 :         if (callback->funcs.decode)
    1607           0 :         {
    1608           0 :             status = callback->funcs.decode(&substream, field, &callback->arg);
    1609             : 
    1610           0 :             if (substream.bytes_left == 0)
    1611           0 :             {
    1612           0 :                 submsg_consumed = true;
    1613           0 :             }
    1614           0 :         }
    1615           0 :     }
    1616             : 
    1617             :     /* Now decode the submessage contents */
    1618           0 :     if (status && !submsg_consumed)
    1619           0 :     {
    1620           0 :         unsigned int flags = 0;
    1621             : 
    1622             :         /* Static required/optional fields are already initialized by top-level
    1623             :          * pb_decode(), no need to initialize them again. */
    1624           0 :         if (PB_ATYPE(field->type) == PB_ATYPE_STATIC &&
    1625           0 :             PB_HTYPE(field->type) != PB_HTYPE_REPEATED)
    1626           0 :         {
    1627           0 :             flags = PB_DECODE_NOINIT;
    1628           0 :         }
    1629             : 
    1630           0 :         status = pb_decode_inner(&substream, field->submsg_desc, field->pData, flags);
    1631           0 :     }
    1632             :     
    1633           0 :     if (!pb_close_string_substream(stream, &substream))
    1634           0 :         return false;
    1635             : 
    1636           0 :     return status;
    1637           0 : }
    1638             : 
    1639             : static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_iter_t *field)
    1640           0 : {
    1641           0 :     uint32_t size;
    1642             : 
    1643           0 :     if (!pb_decode_varint32(stream, &size))
    1644           0 :         return false;
    1645             : 
    1646           0 :     if (size > PB_SIZE_MAX)
    1647           0 :         PB_RETURN_ERROR(stream, "bytes overflow");
    1648             : 
    1649           0 :     if (size == 0)
    1650           0 :     {
    1651             :         /* As a special case, treat empty bytes string as all zeros for fixed_length_bytes. */
    1652           0 :         memset(field->pData, 0, (size_t)field->data_size);
    1653           0 :         return true;
    1654           0 :     }
    1655             : 
    1656           0 :     if (size != field->data_size)
    1657           0 :         PB_RETURN_ERROR(stream, "incorrect fixed length bytes size");
    1658             : 
    1659           0 :     return pb_read(stream, (pb_byte_t*)field->pData, (size_t)field->data_size);
    1660           0 : }
    1661             : 
    1662             : #ifdef PB_CONVERT_DOUBLE_FLOAT
    1663             : bool pb_decode_double_as_float(pb_istream_t *stream, float *dest)
    1664             : {
    1665             :     uint_least8_t sign;
    1666             :     int exponent;
    1667             :     uint32_t mantissa;
    1668             :     uint64_t value;
    1669             :     union { float f; uint32_t i; } out;
    1670             : 
    1671             :     if (!pb_decode_fixed64(stream, &value))
    1672             :         return false;
    1673             : 
    1674             :     /* Decompose input value */
    1675             :     sign = (uint_least8_t)((value >> 63) & 1);
    1676             :     exponent = (int)((value >> 52) & 0x7FF) - 1023;
    1677             :     mantissa = (value >> 28) & 0xFFFFFF; /* Highest 24 bits */
    1678             : 
    1679             :     /* Figure if value is in range representable by floats. */
    1680             :     if (exponent == 1024)
    1681             :     {
    1682             :         /* Special value */
    1683             :         exponent = 128;
    1684             :         mantissa >>= 1;
    1685             :     }
    1686             :     else
    1687             :     {
    1688             :         if (exponent > 127)
    1689             :         {
    1690             :             /* Too large, convert to infinity */
    1691             :             exponent = 128;
    1692             :             mantissa = 0;
    1693             :         }
    1694             :         else if (exponent < -150)
    1695             :         {
    1696             :             /* Too small, convert to zero */
    1697             :             exponent = -127;
    1698             :             mantissa = 0;
    1699             :         }
    1700             :         else if (exponent < -126)
    1701             :         {
    1702             :             /* Denormalized */
    1703             :             mantissa |= 0x1000000;
    1704             :             mantissa >>= (-126 - exponent);
    1705             :             exponent = -127;
    1706             :         }
    1707             : 
    1708             :         /* Round off mantissa */
    1709             :         mantissa = (mantissa + 1) >> 1;
    1710             : 
    1711             :         /* Check if mantissa went over 2.0 */
    1712             :         if (mantissa & 0x800000)
    1713             :         {
    1714             :             exponent += 1;
    1715             :             mantissa &= 0x7FFFFF;
    1716             :             mantissa >>= 1;
    1717             :         }
    1718             :     }
    1719             : 
    1720             :     /* Combine fields */
    1721             :     out.i = mantissa;
    1722             :     out.i |= (uint32_t)(exponent + 127) << 23;
    1723             :     out.i |= (uint32_t)sign << 31;
    1724             : 
    1725             :     *dest = out.f;
    1726             :     return true;
    1727             : }
    1728             : #endif

Generated by: LCOV version 1.14