validation.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include "validation.h"
  2. #include "malloc_wrappers.h"
  3. #include <pb_common.h>
  4. #include <assert.h>
  5. void validate_static(pb_field_iter_t *iter)
  6. {
  7. pb_size_t count = 1;
  8. pb_size_t i;
  9. bool truebool = true;
  10. bool falsebool = false;
  11. if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED && iter->pSize)
  12. {
  13. /* Array count must be between 0 and statically allocated size */
  14. count = *(pb_size_t*)iter->pSize;
  15. assert(count <= iter->array_size);
  16. }
  17. else if (PB_HTYPE(iter->type) == PB_HTYPE_OPTIONAL && iter->pSize)
  18. {
  19. /* Boolean has_ field must have a valid value */
  20. assert(memcmp(iter->pSize, &truebool, sizeof(bool)) == 0 ||
  21. memcmp(iter->pSize, &falsebool, sizeof(bool)) == 0);
  22. }
  23. else if (PB_HTYPE(iter->type) == PB_HTYPE_ONEOF)
  24. {
  25. if (*(pb_size_t*)iter->pSize != iter->tag)
  26. {
  27. /* Some different field in oneof */
  28. return;
  29. }
  30. }
  31. for (i = 0; i < count; i++)
  32. {
  33. void *pData = (char*)iter->pData + iter->data_size * i;
  34. if (PB_LTYPE(iter->type) == PB_LTYPE_STRING)
  35. {
  36. /* String length must be at most statically allocated size */
  37. assert(strlen(pData) + 1 <= iter->data_size);
  38. }
  39. else if (PB_LTYPE(iter->type) == PB_LTYPE_BYTES)
  40. {
  41. /* Bytes length must be at most statically allocated size */
  42. pb_bytes_array_t *bytes = pData;
  43. assert(PB_BYTES_ARRAY_T_ALLOCSIZE(bytes->size) <= iter->data_size);
  44. }
  45. else if (PB_LTYPE(iter->type) == PB_LTYPE_BOOL)
  46. {
  47. /* Bool fields must have valid value */
  48. assert(memcmp(pData, &truebool, sizeof(bool)) == 0 ||
  49. memcmp(pData, &falsebool, sizeof(bool)) == 0);
  50. }
  51. else if (PB_LTYPE_IS_SUBMSG(iter->type))
  52. {
  53. validate_message(pData, 0, iter->submsg_desc);
  54. }
  55. }
  56. }
  57. void validate_pointer(pb_field_iter_t *iter)
  58. {
  59. pb_size_t count = 1;
  60. pb_size_t i;
  61. bool truebool = true;
  62. bool falsebool = false;
  63. if (PB_HTYPE(iter->type) == PB_HTYPE_ONEOF)
  64. {
  65. if (*(pb_size_t*)iter->pSize != iter->tag)
  66. {
  67. /* Some different field in oneof */
  68. return;
  69. }
  70. }
  71. else if (!iter->pData)
  72. {
  73. /* Nothing allocated */
  74. if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED && iter->pSize != &iter->array_size)
  75. {
  76. assert(*(pb_size_t*)iter->pSize == 0);
  77. }
  78. return;
  79. }
  80. if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED)
  81. {
  82. /* Check that enough memory has been allocated for array */
  83. size_t allocated_size = get_allocation_size(iter->pData);
  84. count = *(pb_size_t*)iter->pSize;
  85. assert(allocated_size >= count * iter->data_size);
  86. }
  87. else if (PB_LTYPE(iter->type) != PB_LTYPE_STRING && PB_LTYPE(iter->type) != PB_LTYPE_BYTES)
  88. {
  89. size_t allocated_size = get_allocation_size(iter->pData);
  90. assert(allocated_size >= iter->data_size);
  91. }
  92. for (i = 0; i < count; i++)
  93. {
  94. void *pData = (char*)iter->pData + iter->data_size * i;
  95. if (PB_LTYPE(iter->type) == PB_LTYPE_STRING)
  96. {
  97. /* Check that enough memory is allocated for string and that
  98. the string is properly terminated. */
  99. const char *str = pData;
  100. if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED)
  101. {
  102. /* String arrays are stored as array of pointers */
  103. str = ((const char**)iter->pData)[i];
  104. }
  105. assert(strlen(str) + 1 <= get_allocation_size(str));
  106. }
  107. else if (PB_LTYPE(iter->type) == PB_LTYPE_BYTES)
  108. {
  109. /* Bytes length must be at most statically allocated size */
  110. const pb_bytes_array_t *bytes = pData;
  111. if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED)
  112. {
  113. /* Bytes arrays are stored as array of pointers */
  114. bytes = ((const pb_bytes_array_t**)iter->pData)[i];
  115. }
  116. assert(PB_BYTES_ARRAY_T_ALLOCSIZE(bytes->size) <= get_allocation_size(bytes));
  117. }
  118. else if (PB_LTYPE(iter->type) == PB_LTYPE_BOOL)
  119. {
  120. /* Bool fields must have valid value */
  121. assert(memcmp(pData, &truebool, sizeof(bool)) == 0 ||
  122. memcmp(pData, &falsebool, sizeof(bool)) == 0);
  123. }
  124. else if (PB_LTYPE_IS_SUBMSG(iter->type))
  125. {
  126. validate_message(pData, 0, iter->submsg_desc);
  127. }
  128. }
  129. }
  130. void validate_message(const void *msg, size_t structsize, const pb_msgdesc_t *msgtype)
  131. {
  132. pb_field_iter_t iter;
  133. if (pb_field_iter_begin_const(&iter, msgtype, msg))
  134. {
  135. do
  136. {
  137. if (PB_ATYPE(iter.type) == PB_ATYPE_STATIC)
  138. {
  139. validate_static(&iter);
  140. }
  141. else if (PB_ATYPE(iter.type) == PB_ATYPE_POINTER)
  142. {
  143. validate_pointer(&iter);
  144. }
  145. } while (pb_field_iter_next(&iter));
  146. }
  147. }