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