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