PageRenderTime 22ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/pb_decode.c

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