Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
pb_decode.c
00001 /* pb_decode.c -- decode a protobuf using minimal resources 00002 * 00003 * 2011 Petteri Aimonen <jpa@kapsi.fi> 00004 */ 00005 00006 /* Use the GCC warn_unused_result attribute to check that all return values 00007 * are propagated correctly. On other compilers and gcc before 3.4.0 just 00008 * ignore the annotation. 00009 */ 00010 #if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) 00011 #define checkreturn 00012 #else 00013 #define checkreturn __attribute__((warn_unused_result)) 00014 #endif 00015 00016 #include "pb.h" 00017 #include "pb_decode.h" 00018 #include "pb_common.h" 00019 00020 /************************************** 00021 * Declarations internal to this file * 00022 **************************************/ 00023 00024 typedef bool (*pb_decoder_t)(pb_istream_t *stream, const pb_field_t *field, void *dest) checkreturn; 00025 00026 static bool checkreturn buf_read(pb_istream_t *stream, uint8_t *buf, size_t count); 00027 static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest); 00028 static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, uint8_t *buf, size_t *size); 00029 static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); 00030 static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); 00031 static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); 00032 static void iter_from_extension(pb_field_iter_t *iter, pb_extension_t *extension); 00033 static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type); 00034 static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter); 00035 static bool checkreturn find_extension_field(pb_field_iter_t *iter); 00036 static void pb_field_set_to_default(pb_field_iter_t *iter); 00037 static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct); 00038 static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest); 00039 static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest); 00040 static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest); 00041 static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest); 00042 static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest); 00043 static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest); 00044 static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest); 00045 static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest); 00046 static bool checkreturn pb_skip_varint(pb_istream_t *stream); 00047 static bool checkreturn pb_skip_string(pb_istream_t *stream); 00048 00049 #ifdef PB_ENABLE_MALLOC 00050 static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size); 00051 static bool checkreturn pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *iter); 00052 static void pb_release_single_field(const pb_field_iter_t *iter); 00053 #endif 00054 00055 /* --- Function pointers to field decoders --- 00056 * Order in the array must match pb_action_t LTYPE numbering. 00057 */ 00058 static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = { 00059 &pb_dec_varint, 00060 &pb_dec_uvarint, 00061 &pb_dec_svarint, 00062 &pb_dec_fixed32, 00063 &pb_dec_fixed64, 00064 00065 &pb_dec_bytes, 00066 &pb_dec_string, 00067 &pb_dec_submessage, 00068 NULL /* extensions */ 00069 }; 00070 00071 /******************************* 00072 * pb_istream_t implementation * 00073 *******************************/ 00074 00075 static bool checkreturn buf_read(pb_istream_t *stream, uint8_t *buf, size_t count) 00076 { 00077 uint8_t *source = (uint8_t*)stream->state; 00078 stream->state = source + count; 00079 00080 if (buf != NULL) 00081 { 00082 while (count--) 00083 *buf++ = *source++; 00084 } 00085 00086 return true; 00087 } 00088 00089 bool checkreturn pb_read(pb_istream_t *stream, uint8_t *buf, size_t count) 00090 { 00091 #ifndef PB_BUFFER_ONLY 00092 if (buf == NULL && stream->callback != buf_read) 00093 { 00094 /* Skip input bytes */ 00095 uint8_t tmp[16]; 00096 while (count > 16) 00097 { 00098 if (!pb_read(stream, tmp, 16)) 00099 return false; 00100 00101 count -= 16; 00102 } 00103 00104 return pb_read(stream, tmp, count); 00105 } 00106 #endif 00107 00108 if (stream->bytes_left < count) 00109 PB_RETURN_ERROR(stream, "end-of-stream"); 00110 00111 #ifndef PB_BUFFER_ONLY 00112 if (!stream->callback(stream, buf, count)) 00113 PB_RETURN_ERROR(stream, "io error"); 00114 #else 00115 if (!buf_read(stream, buf, count)) 00116 return false; 00117 #endif 00118 00119 stream->bytes_left -= count; 00120 return true; 00121 } 00122 00123 /* Read a single byte from input stream. buf may not be NULL. 00124 * This is an optimization for the varint decoding. */ 00125 static bool checkreturn pb_readbyte(pb_istream_t *stream, uint8_t *buf) 00126 { 00127 if (stream->bytes_left == 0) 00128 PB_RETURN_ERROR(stream, "end-of-stream"); 00129 00130 #ifndef PB_BUFFER_ONLY 00131 if (!stream->callback(stream, buf, 1)) 00132 PB_RETURN_ERROR(stream, "io error"); 00133 #else 00134 *buf = *(uint8_t*)stream->state; 00135 stream->state = (uint8_t*)stream->state + 1; 00136 #endif 00137 00138 stream->bytes_left--; 00139 00140 return true; 00141 } 00142 00143 pb_istream_t pb_istream_from_buffer(uint8_t *buf, size_t bufsize) 00144 { 00145 pb_istream_t stream; 00146 #ifdef PB_BUFFER_ONLY 00147 stream.callback = NULL; 00148 #else 00149 stream.callback = &buf_read; 00150 #endif 00151 stream.state = buf; 00152 stream.bytes_left = bufsize; 00153 #ifndef PB_NO_ERRMSG 00154 stream.errmsg = NULL; 00155 #endif 00156 return stream; 00157 } 00158 00159 /******************** 00160 * Helper functions * 00161 ********************/ 00162 00163 static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) 00164 { 00165 uint8_t byte; 00166 uint32_t result; 00167 00168 if (!pb_readbyte(stream, &byte)) 00169 return false; 00170 00171 if ((byte & 0x80) == 0) 00172 { 00173 /* Quick case, 1 byte value */ 00174 result = byte; 00175 } 00176 else 00177 { 00178 /* Multibyte case */ 00179 uint8_t bitpos = 7; 00180 result = byte & 0x7F; 00181 00182 do 00183 { 00184 if (bitpos >= 32) 00185 PB_RETURN_ERROR(stream, "varint overflow"); 00186 00187 if (!pb_readbyte(stream, &byte)) 00188 return false; 00189 00190 result |= (uint32_t)(byte & 0x7F) << bitpos; 00191 bitpos = (uint8_t)(bitpos + 7); 00192 } while (byte & 0x80); 00193 } 00194 00195 *dest = result; 00196 return true; 00197 } 00198 00199 bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest) 00200 { 00201 uint8_t byte; 00202 uint8_t bitpos = 0; 00203 uint64_t result = 0; 00204 00205 do 00206 { 00207 if (bitpos >= 64) 00208 PB_RETURN_ERROR(stream, "varint overflow"); 00209 00210 if (!pb_readbyte(stream, &byte)) 00211 return false; 00212 00213 result |= (uint64_t)(byte & 0x7F) << bitpos; 00214 bitpos = (uint8_t)(bitpos + 7); 00215 } while (byte & 0x80); 00216 00217 *dest = result; 00218 return true; 00219 } 00220 00221 bool checkreturn pb_skip_varint(pb_istream_t *stream) 00222 { 00223 uint8_t byte; 00224 do 00225 { 00226 if (!pb_read(stream, &byte, 1)) 00227 return false; 00228 } while (byte & 0x80); 00229 return true; 00230 } 00231 00232 bool checkreturn pb_skip_string(pb_istream_t *stream) 00233 { 00234 uint32_t length; 00235 if (!pb_decode_varint32(stream, &length)) 00236 return false; 00237 00238 return pb_read(stream, NULL, length); 00239 } 00240 00241 bool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof) 00242 { 00243 uint32_t temp; 00244 *eof = false; 00245 *wire_type = (pb_wire_type_t) 0; 00246 *tag = 0; 00247 00248 if (!pb_decode_varint32(stream, &temp)) 00249 { 00250 if (stream->bytes_left == 0) 00251 *eof = true; 00252 00253 return false; 00254 } 00255 00256 if (temp == 0) 00257 { 00258 *eof = true; /* Special feature: allow 0-terminated messages. */ 00259 return false; 00260 } 00261 00262 *tag = temp >> 3; 00263 *wire_type = (pb_wire_type_t)(temp & 7); 00264 return true; 00265 } 00266 00267 bool checkreturn pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type) 00268 { 00269 switch (wire_type) 00270 { 00271 case PB_WT_VARINT: return pb_skip_varint(stream); 00272 case PB_WT_64BIT: return pb_read(stream, NULL, 8); 00273 case PB_WT_STRING: return pb_skip_string(stream); 00274 case PB_WT_32BIT: return pb_read(stream, NULL, 4); 00275 default: PB_RETURN_ERROR(stream, "invalid wire_type"); 00276 } 00277 } 00278 00279 /* Read a raw value to buffer, for the purpose of passing it to callback as 00280 * a substream. Size is maximum size on call, and actual size on return. 00281 */ 00282 static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, uint8_t *buf, size_t *size) 00283 { 00284 size_t max_size = *size; 00285 switch (wire_type) 00286 { 00287 case PB_WT_VARINT: 00288 *size = 0; 00289 do 00290 { 00291 (*size)++; 00292 if (*size > max_size) return false; 00293 if (!pb_read(stream, buf, 1)) return false; 00294 } while (*buf++ & 0x80); 00295 return true; 00296 00297 case PB_WT_64BIT: 00298 *size = 8; 00299 return pb_read(stream, buf, 8); 00300 00301 case PB_WT_32BIT: 00302 *size = 4; 00303 return pb_read(stream, buf, 4); 00304 00305 default: PB_RETURN_ERROR(stream, "invalid wire_type"); 00306 } 00307 } 00308 00309 /* Decode string length from stream and return a substream with limited length. 00310 * Remember to close the substream using pb_close_string_substream(). 00311 */ 00312 bool checkreturn pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream) 00313 { 00314 uint32_t size; 00315 if (!pb_decode_varint32(stream, &size)) 00316 return false; 00317 00318 *substream = *stream; 00319 if (substream->bytes_left < size) 00320 PB_RETURN_ERROR(stream, "parent stream too short"); 00321 00322 substream->bytes_left = size; 00323 stream->bytes_left -= size; 00324 return true; 00325 } 00326 00327 void pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream) 00328 { 00329 stream->state = substream->state; 00330 00331 #ifndef PB_NO_ERRMSG 00332 stream->errmsg = substream->errmsg; 00333 #endif 00334 } 00335 00336 /************************* 00337 * Decode a single field * 00338 *************************/ 00339 00340 static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) 00341 { 00342 pb_type_t type; 00343 pb_decoder_t func; 00344 00345 type = iter->pos->type; 00346 func = PB_DECODERS[PB_LTYPE(type)]; 00347 00348 switch (PB_HTYPE(type)) 00349 { 00350 case PB_HTYPE_REQUIRED: 00351 return func(stream, iter->pos, iter->pData); 00352 00353 case PB_HTYPE_OPTIONAL: 00354 *(bool*)iter->pSize = true; 00355 return func(stream, iter->pos, iter->pData); 00356 00357 case PB_HTYPE_REPEATED: 00358 if (wire_type == PB_WT_STRING 00359 && PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE) 00360 { 00361 /* Packed array */ 00362 bool status = true; 00363 pb_size_t *size = (pb_size_t*)iter->pSize; 00364 pb_istream_t substream; 00365 if (!pb_make_string_substream(stream, &substream)) 00366 return false; 00367 00368 while (substream.bytes_left > 0 && *size < iter->pos->array_size) 00369 { 00370 void *pItem = (uint8_t*)iter->pData + iter->pos->data_size * (*size); 00371 if (!func(&substream, iter->pos, pItem)) 00372 { 00373 status = false; 00374 break; 00375 } 00376 (*size)++; 00377 } 00378 pb_close_string_substream(stream, &substream); 00379 00380 if (substream.bytes_left != 0) 00381 PB_RETURN_ERROR(stream, "array overflow"); 00382 00383 return status; 00384 } 00385 else 00386 { 00387 /* Repeated field */ 00388 pb_size_t *size = (pb_size_t*)iter->pSize; 00389 void *pItem = (uint8_t*)iter->pData + iter->pos->data_size * (*size); 00390 if (*size >= iter->pos->array_size) 00391 PB_RETURN_ERROR(stream, "array overflow"); 00392 00393 (*size)++; 00394 return func(stream, iter->pos, pItem); 00395 } 00396 00397 case PB_HTYPE_ONEOF: 00398 *(pb_size_t*)iter->pSize = iter->pos->tag; 00399 if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE) 00400 { 00401 /* We memset to zero so that any callbacks are set to NULL. 00402 * Then set any default values. */ 00403 memset(iter->pData, 0, iter->pos->data_size); 00404 pb_message_set_to_defaults((const pb_field_t*)iter->pos->ptr, iter->pData); 00405 } 00406 return func(stream, iter->pos, iter->pData); 00407 00408 default: 00409 PB_RETURN_ERROR(stream, "invalid field type"); 00410 } 00411 } 00412 00413 #ifdef PB_ENABLE_MALLOC 00414 /* Allocate storage for the field and store the pointer at iter->pData. 00415 * array_size is the number of entries to reserve in an array. 00416 * Zero size is not allowed, use pb_free() for releasing. 00417 */ 00418 static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size) 00419 { 00420 void *ptr = *(void**)pData; 00421 00422 if (data_size == 0 || array_size == 0) 00423 PB_RETURN_ERROR(stream, "invalid size"); 00424 00425 /* Check for multiplication overflows. 00426 * This code avoids the costly division if the sizes are small enough. 00427 * Multiplication is safe as long as only half of bits are set 00428 * in either multiplicand. 00429 */ 00430 { 00431 const size_t check_limit = (size_t)1 << (sizeof(size_t) * 4); 00432 if (data_size >= check_limit || array_size >= check_limit) 00433 { 00434 const size_t size_max = (size_t)-1; 00435 if (size_max / array_size < data_size) 00436 { 00437 PB_RETURN_ERROR(stream, "size too large"); 00438 } 00439 } 00440 } 00441 00442 /* Allocate new or expand previous allocation */ 00443 /* Note: on failure the old pointer will remain in the structure, 00444 * the message must be freed by caller also on error return. */ 00445 ptr = pb_realloc(ptr, array_size * data_size); 00446 if (ptr == NULL) 00447 PB_RETURN_ERROR(stream, "realloc failed"); 00448 00449 *(void**)pData = ptr; 00450 return true; 00451 } 00452 00453 /* Clear a newly allocated item in case it contains a pointer, or is a submessage. */ 00454 static void initialize_pointer_field(void *pItem, pb_field_iter_t *iter) 00455 { 00456 if (PB_LTYPE(iter->pos->type) == PB_LTYPE_STRING || 00457 PB_LTYPE(iter->pos->type) == PB_LTYPE_BYTES) 00458 { 00459 *(void**)pItem = NULL; 00460 } 00461 else if (PB_LTYPE(iter->pos->type) == PB_LTYPE_SUBMESSAGE) 00462 { 00463 pb_message_set_to_defaults((const pb_field_t *) iter->pos->ptr, pItem); 00464 } 00465 } 00466 #endif 00467 00468 static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) 00469 { 00470 #ifndef PB_ENABLE_MALLOC 00471 PB_UNUSED(wire_type); 00472 PB_UNUSED(iter); 00473 PB_RETURN_ERROR(stream, "no malloc support"); 00474 #else 00475 pb_type_t type; 00476 pb_decoder_t func; 00477 00478 type = iter->pos->type; 00479 func = PB_DECODERS[PB_LTYPE(type)]; 00480 00481 switch (PB_HTYPE(type)) 00482 { 00483 case PB_HTYPE_REQUIRED: 00484 case PB_HTYPE_OPTIONAL: 00485 case PB_HTYPE_ONEOF: 00486 if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE && 00487 *(void**)iter->pData != NULL) 00488 { 00489 /* Duplicate field, have to release the old allocation first. */ 00490 pb_release_single_field(iter); 00491 } 00492 00493 if (PB_HTYPE(type) == PB_HTYPE_ONEOF) 00494 { 00495 *(pb_size_t*)iter->pSize = iter->pos->tag; 00496 } 00497 00498 if (PB_LTYPE(type) == PB_LTYPE_STRING || 00499 PB_LTYPE(type) == PB_LTYPE_BYTES) 00500 { 00501 return func(stream, iter->pos, iter->pData); 00502 } 00503 else 00504 { 00505 if (!allocate_field(stream, iter->pData, iter->pos->data_size, 1)) 00506 return false; 00507 00508 initialize_pointer_field(*(void**)iter->pData, iter); 00509 return func(stream, iter->pos, *(void**)iter->pData); 00510 } 00511 00512 case PB_HTYPE_REPEATED: 00513 if (wire_type == PB_WT_STRING 00514 && PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE) 00515 { 00516 /* Packed array, multiple items come in at once. */ 00517 bool status = true; 00518 pb_size_t *size = (pb_size_t*)iter->pSize; 00519 size_t allocated_size = *size; 00520 void *pItem; 00521 pb_istream_t substream; 00522 00523 if (!pb_make_string_substream(stream, &substream)) 00524 return false; 00525 00526 while (substream.bytes_left) 00527 { 00528 if ((size_t)*size + 1 > allocated_size) 00529 { 00530 /* Allocate more storage. This tries to guess the 00531 * number of remaining entries. Round the division 00532 * upwards. */ 00533 allocated_size += (substream.bytes_left - 1) / iter->pos->data_size + 1; 00534 00535 if (!allocate_field(&substream, iter->pData, iter->pos->data_size, allocated_size)) 00536 { 00537 status = false; 00538 break; 00539 } 00540 } 00541 00542 /* Decode the array entry */ 00543 pItem = *(uint8_t**)iter->pData + iter->pos->data_size * (*size); 00544 initialize_pointer_field(pItem, iter); 00545 if (!func(&substream, iter->pos, pItem)) 00546 { 00547 status = false; 00548 break; 00549 } 00550 00551 if (*size == PB_SIZE_MAX) 00552 { 00553 #ifndef PB_NO_ERRMSG 00554 stream->errmsg = "too many array entries"; 00555 #endif 00556 status = false; 00557 break; 00558 } 00559 00560 (*size)++; 00561 } 00562 pb_close_string_substream(stream, &substream); 00563 00564 return status; 00565 } 00566 else 00567 { 00568 /* Normal repeated field, i.e. only one item at a time. */ 00569 pb_size_t *size = (pb_size_t*)iter->pSize; 00570 void *pItem; 00571 00572 if (*size == PB_SIZE_MAX) 00573 PB_RETURN_ERROR(stream, "too many array entries"); 00574 00575 (*size)++; 00576 if (!allocate_field(stream, iter->pData, iter->pos->data_size, *size)) 00577 return false; 00578 00579 pItem = *(uint8_t**)iter->pData + iter->pos->data_size * (*size - 1); 00580 initialize_pointer_field(pItem, iter); 00581 return func(stream, iter->pos, pItem); 00582 } 00583 00584 default: 00585 PB_RETURN_ERROR(stream, "invalid field type"); 00586 } 00587 #endif 00588 } 00589 00590 static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) 00591 { 00592 pb_callback_t *pCallback = (pb_callback_t*)iter->pData; 00593 00594 #ifdef PB_OLD_CALLBACK_STYLE 00595 void *arg = pCallback->arg; 00596 #else 00597 void **arg = &(pCallback->arg); 00598 #endif 00599 00600 if (pCallback->funcs.decode == NULL) 00601 return pb_skip_field(stream, wire_type); 00602 00603 if (wire_type == PB_WT_STRING) 00604 { 00605 pb_istream_t substream; 00606 00607 if (!pb_make_string_substream(stream, &substream)) 00608 return false; 00609 00610 do 00611 { 00612 if (!pCallback->funcs.decode(&substream, iter->pos, arg)) 00613 PB_RETURN_ERROR(stream, "callback failed"); 00614 } while (substream.bytes_left); 00615 00616 pb_close_string_substream(stream, &substream); 00617 return true; 00618 } 00619 else 00620 { 00621 /* Copy the single scalar value to stack. 00622 * This is required so that we can limit the stream length, 00623 * which in turn allows to use same callback for packed and 00624 * not-packed fields. */ 00625 pb_istream_t substream; 00626 uint8_t buffer[10]; 00627 size_t size = sizeof(buffer); 00628 00629 if (!read_raw_value(stream, wire_type, buffer, &size)) 00630 return false; 00631 substream = pb_istream_from_buffer(buffer, size); 00632 00633 return pCallback->funcs.decode(&substream, iter->pos, arg); 00634 } 00635 } 00636 00637 static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) 00638 { 00639 #ifdef PB_ENABLE_MALLOC 00640 /* When decoding an oneof field, check if there is old data that must be 00641 * released first. */ 00642 if (PB_HTYPE(iter->pos->type) == PB_HTYPE_ONEOF) 00643 { 00644 if (!pb_release_union_field(stream, iter)) 00645 return false; 00646 } 00647 #endif 00648 00649 switch (PB_ATYPE(iter->pos->type)) 00650 { 00651 case PB_ATYPE_STATIC: 00652 return decode_static_field(stream, wire_type, iter); 00653 00654 case PB_ATYPE_POINTER: 00655 return decode_pointer_field(stream, wire_type, iter); 00656 00657 case PB_ATYPE_CALLBACK: 00658 return decode_callback_field(stream, wire_type, iter); 00659 00660 default: 00661 PB_RETURN_ERROR(stream, "invalid field type"); 00662 } 00663 } 00664 00665 static void iter_from_extension(pb_field_iter_t *iter, pb_extension_t *extension) 00666 { 00667 /* Fake a field iterator for the extension field. 00668 * It is not actually safe to advance this iterator, but decode_field 00669 * will not even try to. */ 00670 const pb_field_t *field = (const pb_field_t*)extension->type->arg; 00671 (void)pb_field_iter_begin(iter, field, extension->dest); 00672 iter->pData = extension->dest; 00673 iter->pSize = &extension->found; 00674 00675 if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) 00676 { 00677 /* For pointer extensions, the pointer is stored directly 00678 * in the extension structure. This avoids having an extra 00679 * indirection. */ 00680 iter->pData = &extension->dest; 00681 } 00682 } 00683 00684 /* Default handler for extension fields. Expects a pb_field_t structure 00685 * in extension->type->arg. */ 00686 static bool checkreturn default_extension_decoder(pb_istream_t *stream, 00687 pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type) 00688 { 00689 const pb_field_t *field = (const pb_field_t*)extension->type->arg; 00690 pb_field_iter_t iter; 00691 00692 if (field->tag != tag) 00693 return true; 00694 00695 iter_from_extension(&iter, extension); 00696 extension->found = true; 00697 return decode_field(stream, wire_type, &iter); 00698 } 00699 00700 /* Try to decode an unknown field as an extension field. Tries each extension 00701 * decoder in turn, until one of them handles the field or loop ends. */ 00702 static bool checkreturn decode_extension(pb_istream_t *stream, 00703 uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter) 00704 { 00705 pb_extension_t *extension = *(pb_extension_t* const *)iter->pData; 00706 size_t pos = stream->bytes_left; 00707 00708 while (extension != NULL && pos == stream->bytes_left) 00709 { 00710 bool status; 00711 if (extension->type->decode) 00712 status = extension->type->decode(stream, extension, tag, wire_type); 00713 else 00714 status = default_extension_decoder(stream, extension, tag, wire_type); 00715 00716 if (!status) 00717 return false; 00718 00719 extension = extension->next; 00720 } 00721 00722 return true; 00723 } 00724 00725 /* Step through the iterator until an extension field is found or until all 00726 * entries have been checked. There can be only one extension field per 00727 * message. Returns false if no extension field is found. */ 00728 static bool checkreturn find_extension_field(pb_field_iter_t *iter) 00729 { 00730 const pb_field_t *start = iter->pos; 00731 00732 do { 00733 if (PB_LTYPE(iter->pos->type) == PB_LTYPE_EXTENSION) 00734 return true; 00735 (void)pb_field_iter_next(iter); 00736 } while (iter->pos != start); 00737 00738 return false; 00739 } 00740 00741 /* Initialize message fields to default values, recursively */ 00742 static void pb_field_set_to_default(pb_field_iter_t *iter) 00743 { 00744 pb_type_t type; 00745 type = iter->pos->type; 00746 00747 if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) 00748 { 00749 pb_extension_t *ext = *(pb_extension_t* const *)iter->pData; 00750 while (ext != NULL) 00751 { 00752 pb_field_iter_t ext_iter; 00753 ext->found = false; 00754 iter_from_extension(&ext_iter, ext); 00755 pb_field_set_to_default(&ext_iter); 00756 ext = ext->next; 00757 } 00758 } 00759 else if (PB_ATYPE(type) == PB_ATYPE_STATIC) 00760 { 00761 bool init_data = true; 00762 if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL) 00763 { 00764 /* Set has_field to false. Still initialize the optional field 00765 * itself also. */ 00766 *(bool*)iter->pSize = false; 00767 } 00768 else if (PB_HTYPE(type) == PB_HTYPE_REPEATED || 00769 PB_HTYPE(type) == PB_HTYPE_ONEOF) 00770 { 00771 /* REPEATED: Set array count to 0, no need to initialize contents. 00772 ONEOF: Set which_field to 0. */ 00773 *(pb_size_t*)iter->pSize = 0; 00774 init_data = false; 00775 } 00776 00777 if (init_data) 00778 { 00779 if (PB_LTYPE(iter->pos->type) == PB_LTYPE_SUBMESSAGE) 00780 { 00781 /* Initialize submessage to defaults */ 00782 pb_message_set_to_defaults((const pb_field_t *) iter->pos->ptr, iter->pData); 00783 } 00784 else if (iter->pos->ptr != NULL) 00785 { 00786 /* Initialize to default value */ 00787 memcpy(iter->pData, iter->pos->ptr, iter->pos->data_size); 00788 } 00789 else 00790 { 00791 /* Initialize to zeros */ 00792 memset(iter->pData, 0, iter->pos->data_size); 00793 } 00794 } 00795 } 00796 else if (PB_ATYPE(type) == PB_ATYPE_POINTER) 00797 { 00798 /* Initialize the pointer to NULL. */ 00799 *(void**)iter->pData = NULL; 00800 00801 /* Initialize array count to 0. */ 00802 if (PB_HTYPE(type) == PB_HTYPE_REPEATED || 00803 PB_HTYPE(type) == PB_HTYPE_ONEOF) 00804 { 00805 *(pb_size_t*)iter->pSize = 0; 00806 } 00807 } 00808 else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK) 00809 { 00810 /* Don't overwrite callback */ 00811 } 00812 } 00813 00814 static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct) 00815 { 00816 pb_field_iter_t iter; 00817 00818 if (!pb_field_iter_begin(&iter, fields, dest_struct)) 00819 return; /* Empty message type */ 00820 00821 do 00822 { 00823 pb_field_set_to_default(&iter); 00824 } while (pb_field_iter_next(&iter)); 00825 } 00826 00827 /********************* 00828 * Decode all fields * 00829 *********************/ 00830 00831 bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) 00832 { 00833 uint8_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 7) / 8] = {0, 0, 0, 0, 0, 0, 0, 0}; 00834 uint32_t extension_range_start = 0; 00835 pb_field_iter_t iter; 00836 00837 /* Return value ignored, as empty message types will be correctly handled by 00838 * pb_field_iter_find() anyway. */ 00839 (void)pb_field_iter_begin(&iter, fields, dest_struct); 00840 00841 while (stream->bytes_left) 00842 { 00843 uint32_t tag; 00844 pb_wire_type_t wire_type; 00845 bool eof; 00846 00847 if (!pb_decode_tag(stream, &wire_type, &tag, &eof)) 00848 { 00849 if (eof) 00850 break; 00851 else 00852 return false; 00853 } 00854 00855 if (!pb_field_iter_find(&iter, tag)) 00856 { 00857 /* No match found, check if it matches an extension. */ 00858 if (tag >= extension_range_start) 00859 { 00860 if (!find_extension_field(&iter)) 00861 extension_range_start = (uint32_t)-1; 00862 else 00863 extension_range_start = iter.pos->tag; 00864 00865 if (tag >= extension_range_start) 00866 { 00867 size_t pos = stream->bytes_left; 00868 00869 if (!decode_extension(stream, tag, wire_type, &iter)) 00870 return false; 00871 00872 if (pos != stream->bytes_left) 00873 { 00874 /* The field was handled */ 00875 continue; 00876 } 00877 } 00878 } 00879 00880 /* No match found, skip data */ 00881 if (!pb_skip_field(stream, wire_type)) 00882 return false; 00883 continue; 00884 } 00885 00886 if (PB_HTYPE(iter.pos->type) == PB_HTYPE_REQUIRED 00887 && iter.required_field_index < PB_MAX_REQUIRED_FIELDS) 00888 { 00889 uint8_t tmp = (uint8_t)(1 << (iter.required_field_index & 7)); 00890 fields_seen[iter.required_field_index >> 3] |= tmp; 00891 } 00892 00893 if (!decode_field(stream, wire_type, &iter)) 00894 return false; 00895 } 00896 00897 /* Check that all required fields were present. */ 00898 { 00899 /* First figure out the number of required fields by 00900 * seeking to the end of the field array. Usually we 00901 * are already close to end after decoding. 00902 */ 00903 unsigned req_field_count; 00904 pb_type_t last_type; 00905 unsigned i; 00906 do { 00907 req_field_count = iter.required_field_index; 00908 last_type = iter.pos->type; 00909 } while (pb_field_iter_next(&iter)); 00910 00911 /* Fixup if last field was also required. */ 00912 if (PB_HTYPE(last_type) == PB_HTYPE_REQUIRED && iter.pos->tag != 0) 00913 req_field_count++; 00914 00915 /* Check the whole bytes */ 00916 for (i = 0; i < (req_field_count >> 3); i++) 00917 { 00918 if (fields_seen[i] != 0xFF) 00919 PB_RETURN_ERROR(stream, "missing required field"); 00920 } 00921 00922 /* Check the remaining bits */ 00923 if (fields_seen[req_field_count >> 3] != (0xFF >> (8 - (req_field_count & 7)))) 00924 PB_RETURN_ERROR(stream, "missing required field"); 00925 } 00926 00927 return true; 00928 } 00929 00930 bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) 00931 { 00932 bool status; 00933 pb_message_set_to_defaults(fields, dest_struct); 00934 status = pb_decode_noinit(stream, fields, dest_struct); 00935 00936 #ifdef PB_ENABLE_MALLOC 00937 if (!status) 00938 pb_release(fields, dest_struct); 00939 #endif 00940 00941 return status; 00942 } 00943 00944 bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) 00945 { 00946 pb_istream_t substream; 00947 bool status; 00948 00949 if (!pb_make_string_substream(stream, &substream)) 00950 return false; 00951 00952 status = pb_decode(&substream, fields, dest_struct); 00953 pb_close_string_substream(stream, &substream); 00954 return status; 00955 } 00956 00957 #ifdef PB_ENABLE_MALLOC 00958 /* Given an oneof field, if there has already been a field inside this oneof, 00959 * release it before overwriting with a different one. */ 00960 static bool pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *iter) 00961 { 00962 pb_size_t old_tag = *(pb_size_t*)iter->pSize; /* Previous which_ value */ 00963 pb_size_t new_tag = iter->pos->tag; /* New which_ value */ 00964 00965 if (old_tag == 0) 00966 return true; /* Ok, no old data in union */ 00967 00968 if (old_tag == new_tag) 00969 return true; /* Ok, old data is of same type => merge */ 00970 00971 /* Release old data. The find can fail if the message struct contains 00972 * invalid data. */ 00973 if (!pb_field_iter_find(iter, old_tag)) 00974 PB_RETURN_ERROR(stream, "invalid union tag"); 00975 00976 pb_release_single_field(iter); 00977 00978 /* Restore iterator to where it should be. 00979 * This shouldn't fail unless the pb_field_t structure is corrupted. */ 00980 if (!pb_field_iter_find(iter, new_tag)) 00981 PB_RETURN_ERROR(stream, "iterator error"); 00982 00983 return true; 00984 } 00985 00986 static void pb_release_single_field(const pb_field_iter_t *iter) 00987 { 00988 pb_type_t type; 00989 type = iter->pos->type; 00990 00991 if (PB_HTYPE(type) == PB_HTYPE_ONEOF) 00992 { 00993 if (*(pb_size_t*)iter->pSize != iter->pos->tag) 00994 return; /* This is not the current field in the union */ 00995 } 00996 00997 /* Release anything contained inside an extension or submsg. 00998 * This has to be done even if the submsg itself is statically 00999 * allocated. */ 01000 if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) 01001 { 01002 /* Release fields from all extensions in the linked list */ 01003 pb_extension_t *ext = *(pb_extension_t**)iter->pData; 01004 while (ext != NULL) 01005 { 01006 pb_field_iter_t ext_iter; 01007 iter_from_extension(&ext_iter, ext); 01008 pb_release_single_field(&ext_iter); 01009 ext = ext->next; 01010 } 01011 } 01012 else if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE) 01013 { 01014 /* Release fields in submessage or submsg array */ 01015 void *pItem = iter->pData; 01016 pb_size_t count = 1; 01017 01018 if (PB_ATYPE(type) == PB_ATYPE_POINTER) 01019 { 01020 pItem = *(void**)iter->pData; 01021 } 01022 01023 if (PB_HTYPE(type) == PB_HTYPE_REPEATED) 01024 { 01025 count = *(pb_size_t*)iter->pSize; 01026 } 01027 01028 if (pItem) 01029 { 01030 while (count--) 01031 { 01032 pb_release((const pb_field_t*)iter->pos->ptr, pItem); 01033 pItem = (uint8_t*)pItem + iter->pos->data_size; 01034 } 01035 } 01036 } 01037 01038 if (PB_ATYPE(type) == PB_ATYPE_POINTER) 01039 { 01040 if (PB_HTYPE(type) == PB_HTYPE_REPEATED && 01041 (PB_LTYPE(type) == PB_LTYPE_STRING || 01042 PB_LTYPE(type) == PB_LTYPE_BYTES)) 01043 { 01044 /* Release entries in repeated string or bytes array */ 01045 void **pItem = *(void***)iter->pData; 01046 pb_size_t count = *(pb_size_t*)iter->pSize; 01047 while (count--) 01048 { 01049 pb_free(*pItem); 01050 *pItem++ = NULL; 01051 } 01052 } 01053 01054 if (PB_HTYPE(type) == PB_HTYPE_REPEATED) 01055 { 01056 /* We are going to release the array, so set the size to 0 */ 01057 *(pb_size_t*)iter->pSize = 0; 01058 } 01059 01060 /* Release main item */ 01061 pb_free(*(void**)iter->pData); 01062 *(void**)iter->pData = NULL; 01063 } 01064 } 01065 01066 void pb_release(const pb_field_t fields[], void *dest_struct) 01067 { 01068 pb_field_iter_t iter; 01069 01070 if (!pb_field_iter_begin(&iter, fields, dest_struct)) 01071 return; /* Empty message type */ 01072 01073 do 01074 { 01075 pb_release_single_field(&iter); 01076 } while (pb_field_iter_next(&iter)); 01077 } 01078 #endif 01079 01080 /* Field decoders */ 01081 01082 bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest) 01083 { 01084 uint64_t value; 01085 if (!pb_decode_varint(stream, &value)) 01086 return false; 01087 01088 if (value & 1) 01089 *dest = (int64_t)(~(value >> 1)); 01090 else 01091 *dest = (int64_t)(value >> 1); 01092 01093 return true; 01094 } 01095 01096 bool pb_decode_fixed32(pb_istream_t *stream, void *dest) 01097 { 01098 #ifdef __BIG_ENDIAN__ 01099 uint8_t *bytes = (uint8_t*)dest; 01100 uint8_t lebytes[4]; 01101 01102 if (!pb_read(stream, lebytes, 4)) 01103 return false; 01104 01105 bytes[0] = lebytes[3]; 01106 bytes[1] = lebytes[2]; 01107 bytes[2] = lebytes[1]; 01108 bytes[3] = lebytes[0]; 01109 return true; 01110 #else 01111 return pb_read(stream, (uint8_t*)dest, 4); 01112 #endif 01113 } 01114 01115 bool pb_decode_fixed64(pb_istream_t *stream, void *dest) 01116 { 01117 #ifdef __BIG_ENDIAN__ 01118 uint8_t *bytes = (uint8_t*)dest; 01119 uint8_t lebytes[8]; 01120 01121 if (!pb_read(stream, lebytes, 8)) 01122 return false; 01123 01124 bytes[0] = lebytes[7]; 01125 bytes[1] = lebytes[6]; 01126 bytes[2] = lebytes[5]; 01127 bytes[3] = lebytes[4]; 01128 bytes[4] = lebytes[3]; 01129 bytes[5] = lebytes[2]; 01130 bytes[6] = lebytes[1]; 01131 bytes[7] = lebytes[0]; 01132 return true; 01133 #else 01134 return pb_read(stream, (uint8_t*)dest, 8); 01135 #endif 01136 } 01137 01138 static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest) 01139 { 01140 uint64_t value; 01141 int64_t svalue; 01142 int64_t clamped; 01143 if (!pb_decode_varint(stream, &value)) 01144 return false; 01145 01146 /* See issue 97: Google's C++ protobuf allows negative varint values to 01147 * be cast as int32_t, instead of the int64_t that should be used when 01148 * encoding. Previous nanopb versions had a bug in encoding. In order to 01149 * not break decoding of such messages, we cast <=32 bit fields to 01150 * int32_t first to get the sign correct. 01151 */ 01152 if (field->data_size == 8) 01153 svalue = (int64_t)value; 01154 else 01155 svalue = (int32_t)value; 01156 01157 switch (field->data_size) 01158 { 01159 case 1: clamped = *(int8_t*)dest = (int8_t)svalue; break; 01160 case 2: clamped = *(int16_t*)dest = (int16_t)svalue; break; 01161 case 4: clamped = *(int32_t*)dest = (int32_t)svalue; break; 01162 case 8: clamped = *(int64_t*)dest = svalue; break; 01163 default: PB_RETURN_ERROR(stream, "invalid data_size"); 01164 } 01165 01166 if (clamped != svalue) 01167 PB_RETURN_ERROR(stream, "integer too large"); 01168 01169 return true; 01170 } 01171 01172 static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest) 01173 { 01174 uint64_t value, clamped; 01175 if (!pb_decode_varint(stream, &value)) 01176 return false; 01177 01178 switch (field->data_size) 01179 { 01180 case 1: clamped = *(uint8_t*)dest = (uint8_t)value; break; 01181 case 2: clamped = *(uint16_t*)dest = (uint16_t)value; break; 01182 case 4: clamped = *(uint32_t*)dest = (uint32_t)value; break; 01183 case 8: clamped = *(uint64_t*)dest = value; break; 01184 default: PB_RETURN_ERROR(stream, "invalid data_size"); 01185 } 01186 01187 if (clamped != value) 01188 PB_RETURN_ERROR(stream, "integer too large"); 01189 01190 return true; 01191 } 01192 01193 static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest) 01194 { 01195 int64_t value, clamped; 01196 if (!pb_decode_svarint(stream, &value)) 01197 return false; 01198 01199 switch (field->data_size) 01200 { 01201 case 1: clamped = *(int8_t*)dest = (int8_t)value; break; 01202 case 2: clamped = *(int16_t*)dest = (int16_t)value; break; 01203 case 4: clamped = *(int32_t*)dest = (int32_t)value; break; 01204 case 8: clamped = *(int64_t*)dest = value; break; 01205 default: PB_RETURN_ERROR(stream, "invalid data_size"); 01206 } 01207 01208 if (clamped != value) 01209 PB_RETURN_ERROR(stream, "integer too large"); 01210 01211 return true; 01212 } 01213 01214 static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest) 01215 { 01216 PB_UNUSED(field); 01217 return pb_decode_fixed32(stream, dest); 01218 } 01219 01220 static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest) 01221 { 01222 PB_UNUSED(field); 01223 return pb_decode_fixed64(stream, dest); 01224 } 01225 01226 static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest) 01227 { 01228 uint32_t size; 01229 size_t alloc_size; 01230 pb_bytes_array_t *bdest; 01231 01232 if (!pb_decode_varint32(stream, &size)) 01233 return false; 01234 01235 if (size > PB_SIZE_MAX) 01236 PB_RETURN_ERROR(stream, "bytes overflow"); 01237 01238 alloc_size = PB_BYTES_ARRAY_T_ALLOCSIZE(size); 01239 if (size > alloc_size) 01240 PB_RETURN_ERROR(stream, "size too large"); 01241 01242 if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) 01243 { 01244 #ifndef PB_ENABLE_MALLOC 01245 PB_RETURN_ERROR(stream, "no malloc support"); 01246 #else 01247 if (!allocate_field(stream, dest, alloc_size, 1)) 01248 return false; 01249 bdest = *(pb_bytes_array_t**)dest; 01250 #endif 01251 } 01252 else 01253 { 01254 if (alloc_size > field->data_size) 01255 PB_RETURN_ERROR(stream, "bytes overflow"); 01256 bdest = (pb_bytes_array_t*)dest; 01257 } 01258 01259 bdest->size = (pb_size_t)size; 01260 return pb_read(stream, bdest->bytes, size); 01261 } 01262 01263 static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest) 01264 { 01265 uint32_t size; 01266 size_t alloc_size; 01267 bool status; 01268 if (!pb_decode_varint32(stream, &size)) 01269 return false; 01270 01271 /* Space for null terminator */ 01272 alloc_size = size + 1; 01273 01274 if (alloc_size < size) 01275 PB_RETURN_ERROR(stream, "size too large"); 01276 01277 if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) 01278 { 01279 #ifndef PB_ENABLE_MALLOC 01280 PB_RETURN_ERROR(stream, "no malloc support"); 01281 #else 01282 if (!allocate_field(stream, dest, alloc_size, 1)) 01283 return false; 01284 dest = *(void**)dest; 01285 #endif 01286 } 01287 else 01288 { 01289 if (alloc_size > field->data_size) 01290 PB_RETURN_ERROR(stream, "string overflow"); 01291 } 01292 01293 status = pb_read(stream, (uint8_t*)dest, size); 01294 *((uint8_t*)dest + size) = 0; 01295 return status; 01296 } 01297 01298 static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest) 01299 { 01300 bool status; 01301 pb_istream_t substream; 01302 const pb_field_t* submsg_fields = (const pb_field_t*)field->ptr; 01303 01304 if (!pb_make_string_substream(stream, &substream)) 01305 return false; 01306 01307 if (field->ptr == NULL) 01308 PB_RETURN_ERROR(stream, "invalid field descriptor"); 01309 01310 /* New array entries need to be initialized, while required and optional 01311 * submessages have already been initialized in the top-level pb_decode. */ 01312 if (PB_HTYPE(field->type) == PB_HTYPE_REPEATED) 01313 status = pb_decode(&substream, submsg_fields, dest); 01314 else 01315 status = pb_decode_noinit(&substream, submsg_fields, dest); 01316 01317 pb_close_string_substream(stream, &substream); 01318 return status; 01319 } 01320
Generated on Fri Sep 23 2022 19:29:17 by
1.7.2