1 #include <r_anal.h>
2 #include <r_parse.h>
3 
4 #include "minunit.h"
5 #include "test_sdb.h"
6 
setup_sdb_for_struct(Sdb * res)7 static void setup_sdb_for_struct(Sdb *res) {
8 	// "td struct kappa {int bar;int cow;};"
9 	sdb_set (res, "kappa", "struct", 0);
10 	sdb_set (res, "struct.kappa", "bar,cow", 0);
11 	sdb_set (res, "struct.kappa.bar", "int32_t,0,0", 0);
12 	sdb_set (res, "struct.kappa.cow", "int32_t,4,0", 0);
13 }
14 
setup_sdb_for_union(Sdb * res)15 static void setup_sdb_for_union(Sdb *res) {
16 	// "td union kappa {int bar;int cow;};"
17 	sdb_set (res, "kappa", "union", 0);
18 	sdb_set (res, "union.kappa", "bar,cow", 0);
19 	sdb_set (res, "union.kappa.bar", "int32_t,0,0", 0);
20 	sdb_set (res, "union.kappa.cow", "int32_t,0,0", 0);
21 }
22 
setup_sdb_for_enum(Sdb * res)23 static void setup_sdb_for_enum(Sdb *res) {
24 	// "td enum foo { firstCase=1, secondCase=2,};"
25 	sdb_set (res, "foo", "enum", 0);
26 	sdb_set (res, "enum.foo", "firstCase,secondCase", 0);
27 	sdb_set (res, "enum.foo.firstCase", "0x1", 0);
28 	sdb_set (res, "enum.foo.secondCase", "0x2", 0);
29 	sdb_set (res, "enum.foo.0x1", "firstCase", 0);
30 	sdb_set (res, "enum.foo.0x2", "secondCase", 0);
31 }
32 
setup_sdb_for_typedef(Sdb * res)33 static void setup_sdb_for_typedef(Sdb *res) {
34 	// td typedef char *string;
35 	sdb_set (res, "string", "typedef", 0);
36 	sdb_set (res, "typedef.string", "char *", 0);
37 }
38 
setup_sdb_for_atomic(Sdb * res)39 static void setup_sdb_for_atomic(Sdb *res) {
40 	sdb_set (res, "char", "type", 0);
41 	sdb_set (res, "type.char.size", "8", 0);
42 	sdb_set (res, "type.char", "c", 0);
43 }
44 
setup_sdb_for_not_found(Sdb * res)45 static void setup_sdb_for_not_found(Sdb *res) {
46 	// malformed type states
47 	sdb_set (res, "foo", "enum", 0);
48 	sdb_set (res, "bar", "struct", 0);
49 	sdb_set (res, "quax", "union", 0);
50 	sdb_set (res, "enum.foo", "aa,bb", 0);
51 	sdb_set (res, "struct.bar", "cc,dd", 0);
52 	sdb_set (res, "union.quax", "ee,ff", 0);
53 
54 	sdb_set (res, "omega", "struct", 0);
55 	sdb_set (res, "struct.omega", "ee,ff,gg", 0);
56 	sdb_set (res, "struct.omega.ee", "0,1", 0);
57 	sdb_set (res, "struct.omega.ff", "", 0);
58 }
59 
test_anal_get_base_type_struct(void)60 static bool test_anal_get_base_type_struct(void) {
61 	RAnal *anal = r_anal_new ();
62 	mu_assert_notnull (anal, "Couldn't create new RAnal");
63 	mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
64 
65 	setup_sdb_for_struct (anal->sdb_types);
66 
67 	RAnalBaseType *base = r_anal_get_base_type (anal, "kappa");
68 	mu_assert_notnull (base, "Couldn't create get base type of struct \"kappa\"");
69 
70 	mu_assert_eq (R_ANAL_BASE_TYPE_KIND_STRUCT, base->kind, "Wrong base type");
71 	mu_assert_streq (base->name, "kappa", "type name");
72 
73 	RAnalStructMember *member;
74 
75 	member = r_vector_index_ptr (&base->struct_data.members, 0);
76 	mu_assert_eq (member->offset, 0, "Incorrect offset for struct member");
77 	mu_assert_streq (member->type, "int32_t", "Incorrect type for struct member");
78 	mu_assert_streq (member->name, "bar", "Incorrect name for struct member");
79 
80 	member = r_vector_index_ptr (&base->struct_data.members, 1);
81 	mu_assert_eq (member->offset, 4, "Incorrect offset for struct member");
82 	mu_assert_streq (member->type, "int32_t", "Incorrect type for struct member");
83 	mu_assert_streq (member->name, "cow", "Incorrect name for struct member");
84 
85 	r_anal_base_type_free (base);
86 	r_anal_free (anal);
87 	mu_end;
88 }
89 
test_anal_save_base_type_struct(void)90 static bool test_anal_save_base_type_struct(void) {
91 	RAnal *anal = r_anal_new ();
92 	mu_assert_notnull (anal, "Couldn't create new RAnal");
93 	mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
94 
95 	RAnalBaseType *base = r_anal_base_type_new (R_ANAL_BASE_TYPE_KIND_STRUCT);
96 	base->name = strdup ("kappa");
97 
98 	RAnalStructMember member = {
99 		.offset = 0,
100 		.type = strdup ("int32_t"),
101 		.name = strdup ("bar")
102 	};
103 	r_vector_push (&base->struct_data.members, &member);
104 
105 	member.offset = 4;
106 	member.type = strdup ("int32_t");
107 	member.name = strdup ("cow");
108 	r_vector_push (&base->struct_data.members, &member);
109 
110 	r_anal_save_base_type (anal, base);
111 	r_anal_base_type_free (base);
112 
113 	Sdb *reg = sdb_new0 ();
114 	setup_sdb_for_struct (reg);
115 	assert_sdb_eq (anal->sdb_types, reg, "save struct type");
116 	sdb_free (reg);
117 
118 	r_anal_free (anal);
119 	mu_end;
120 }
121 
test_anal_get_base_type_union(void)122 static bool test_anal_get_base_type_union(void) {
123 	RAnal *anal = r_anal_new ();
124 	mu_assert_notnull (anal, "Couldn't create new RAnal");
125 	mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
126 
127 	setup_sdb_for_union (anal->sdb_types);
128 
129 	RAnalBaseType *base = r_anal_get_base_type (anal, "kappa");
130 	mu_assert_notnull (base, "Couldn't create get base type of union \"kappa\"");
131 
132 	mu_assert_eq (R_ANAL_BASE_TYPE_KIND_UNION, base->kind, "Wrong base type");
133 	mu_assert_streq (base->name, "kappa", "type name");
134 
135 	RAnalUnionMember *member;
136 
137 	member = r_vector_index_ptr (&base->union_data.members, 0);
138 	mu_assert_streq (member->type, "int32_t", "Incorrect type for union member");
139 	mu_assert_streq (member->name, "bar", "Incorrect name for union member");
140 
141 	member = r_vector_index_ptr (&base->union_data.members, 1);
142 	mu_assert_streq (member->type, "int32_t", "Incorrect type for union member");
143 	mu_assert_streq (member->name, "cow", "Incorrect name for union member");
144 
145 	r_anal_base_type_free (base);
146 	r_anal_free (anal);
147 	mu_end;
148 }
149 
test_anal_save_base_type_union(void)150 static bool test_anal_save_base_type_union(void) {
151 	RAnal *anal = r_anal_new ();
152 	mu_assert_notnull (anal, "Couldn't create new RAnal");
153 	mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
154 
155 	RAnalBaseType *base = r_anal_base_type_new (R_ANAL_BASE_TYPE_KIND_UNION);
156 	base->name = strdup ("kappa");
157 
158 	RAnalUnionMember member = {
159 		.offset = 0,
160 		.type = strdup ("int32_t"),
161 		.name = strdup ("bar")
162 	};
163 	r_vector_push (&base->union_data.members, &member);
164 
165 	member.offset = 0;
166 	member.type = strdup ("int32_t");
167 	member.name = strdup ("cow");
168 	r_vector_push (&base->union_data.members, &member);
169 
170 	r_anal_save_base_type (anal, base);
171 	r_anal_base_type_free (base);
172 
173 	Sdb *reg = sdb_new0 ();
174 	setup_sdb_for_union (reg);
175 	assert_sdb_eq (anal->sdb_types, reg, "save union type");
176 	sdb_free (reg);
177 
178 	r_anal_free (anal);
179 	mu_end;
180 }
181 
test_anal_get_base_type_enum(void)182 static bool test_anal_get_base_type_enum(void) {
183 	RAnal *anal = r_anal_new ();
184 	mu_assert_notnull (anal, "Couldn't create new RAnal");
185 	mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
186 
187 	setup_sdb_for_enum (anal->sdb_types);
188 
189 	RAnalBaseType *base = r_anal_get_base_type (anal, "foo");
190 	mu_assert_notnull (base, "Couldn't create get base type of enum \"foo\"");
191 
192 	mu_assert_eq (R_ANAL_BASE_TYPE_KIND_ENUM, base->kind, "Wrong base type");
193 	mu_assert_streq (base->name, "foo", "type name");
194 
195 	RAnalEnumCase *cas = r_vector_index_ptr (&base->enum_data.cases, 0);
196 	mu_assert_eq (cas->val, 1, "Incorrect value for enum case");
197 	mu_assert_streq (cas->name, "firstCase", "Incorrect name for enum case");
198 
199 	cas = r_vector_index_ptr (&base->enum_data.cases, 1);
200 	mu_assert_eq (cas->val, 2, "Incorrect value for enum case");
201 	mu_assert_streq (cas->name, "secondCase", "Incorrect name for enum case");
202 
203 	r_anal_base_type_free (base);
204 	r_anal_free (anal);
205 	mu_end;
206 }
207 
test_anal_save_base_type_enum(void)208 static bool test_anal_save_base_type_enum(void) {
209 	RAnal *anal = r_anal_new ();
210 	mu_assert_notnull (anal, "Couldn't create new RAnal");
211 	mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
212 
213 	RAnalBaseType *base = r_anal_base_type_new (R_ANAL_BASE_TYPE_KIND_ENUM);
214 	base->name = strdup ("foo");
215 
216 	RAnalEnumCase cas = {
217 		.name = strdup ("firstCase"),
218 		.val = 1
219 	};
220 	r_vector_push (&base->enum_data.cases, &cas);
221 
222 	cas.name = strdup ("secondCase");
223 	cas.val = 2;
224 	r_vector_push (&base->enum_data.cases, &cas);
225 
226 	r_anal_save_base_type (anal, base);
227 	r_anal_base_type_free (base);
228 
229 	Sdb *reg = sdb_new0 ();
230 	setup_sdb_for_enum (reg);
231 	assert_sdb_eq (anal->sdb_types, reg, "save enum type");
232 	sdb_free (reg);
233 
234 	r_anal_free (anal);
235 	mu_end;
236 }
237 
test_anal_get_base_type_typedef(void)238 static bool test_anal_get_base_type_typedef(void) {
239 	RAnal *anal = r_anal_new ();
240 	mu_assert_notnull (anal, "Couldn't create new RAnal");
241 	mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
242 
243 	setup_sdb_for_typedef (anal->sdb_types);
244 
245 	RAnalBaseType *base = r_anal_get_base_type (anal, "string");
246 	mu_assert_notnull (base, "Couldn't create get base type of typedef \"string\"");
247 
248 	mu_assert_eq (R_ANAL_BASE_TYPE_KIND_TYPEDEF, base->kind, "Wrong base type");
249 	mu_assert_streq (base->name, "string", "type name");
250 	mu_assert_streq (base->type, "char *", "typedefd type");
251 
252 	r_anal_base_type_free (base);
253 	r_anal_free (anal);
254 	mu_end;
255 }
256 
test_anal_save_base_type_typedef(void)257 static bool test_anal_save_base_type_typedef(void) {
258 	RAnal *anal = r_anal_new ();
259 	mu_assert_notnull (anal, "Couldn't create new RAnal");
260 	mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
261 
262 	RAnalBaseType *base = r_anal_base_type_new (R_ANAL_BASE_TYPE_KIND_TYPEDEF);
263 	base->name = strdup ("string");
264 	base->type = strdup ("char *");
265 
266 	r_anal_save_base_type (anal, base);
267 	r_anal_base_type_free (base);
268 
269 	Sdb *reg = sdb_new0 ();
270 	setup_sdb_for_typedef (reg);
271 	assert_sdb_eq (anal->sdb_types, reg, "save typedef type");
272 	sdb_free (reg);
273 
274 	r_anal_free (anal);
275 	mu_end;
276 }
277 
test_anal_get_base_type_atomic(void)278 static bool test_anal_get_base_type_atomic(void) {
279 	RAnal *anal = r_anal_new ();
280 	mu_assert_notnull (anal, "Couldn't create new RAnal");
281 	mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
282 
283 	setup_sdb_for_atomic (anal->sdb_types);
284 
285 	RAnalBaseType *base = r_anal_get_base_type (anal, "char");
286 	mu_assert_notnull (base, "Couldn't create get base type of atomic type \"char\"");
287 
288 	mu_assert_eq (R_ANAL_BASE_TYPE_KIND_ATOMIC, base->kind, "Wrong base type");
289 	mu_assert_streq (base->name, "char", "type name");
290 	mu_assert_streq (base->type, "c", "atomic type type");
291 	mu_assert_eq (base->size, 8, "atomic type size");
292 
293 	r_anal_base_type_free (base);
294 	r_anal_free (anal);
295 	mu_end;
296 }
297 
test_anal_save_base_type_atomic(void)298 static bool test_anal_save_base_type_atomic(void) {
299 	RAnal *anal = r_anal_new ();
300 	mu_assert_notnull (anal, "Couldn't create new RAnal");
301 	mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
302 
303 	RAnalBaseType *base = r_anal_base_type_new (R_ANAL_BASE_TYPE_KIND_ATOMIC);
304 	base->name = strdup ("char");
305 	base->type = strdup ("c");
306 	base->size = 8;
307 
308 	r_anal_save_base_type (anal, base);
309 	r_anal_base_type_free (base);
310 
311 	Sdb *reg = sdb_new0 ();
312 	setup_sdb_for_atomic (reg);
313 	assert_sdb_eq (anal->sdb_types, reg, "save atomic type");
314 	sdb_free (reg);
315 
316 	r_anal_free (anal);
317 	mu_end;
318 }
319 
test_anal_get_base_type_not_found(void)320 static bool test_anal_get_base_type_not_found(void) {
321 	RAnal *anal = r_anal_new ();
322 	setup_sdb_for_not_found (anal->sdb_types);
323 
324 	mu_assert_notnull (anal, "Couldn't create new RAnal");
325 	mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
326 
327 	RAnalBaseType *base = r_anal_get_base_type (anal, "non_existant23321312___");
328 	mu_assert_null (base, "Should find nothing");
329 	base = r_anal_get_base_type (anal, "foo");
330 	mu_assert_null (base, "Should find nothing");
331 	base = r_anal_get_base_type (anal, "bar");
332 	mu_assert_null (base, "Should find nothing");
333 	base = r_anal_get_base_type (anal, "quax");
334 	mu_assert_null (base, "Should find nothing");
335 	base = r_anal_get_base_type (anal, "omega");
336 	mu_assert_null (base, "Should find nothing");
337 
338 	r_anal_free (anal);
339 	mu_end;
340 }
341 
all_tests(void)342 int all_tests(void) {
343 	mu_run_test (test_anal_get_base_type_struct);
344 	mu_run_test (test_anal_save_base_type_struct);
345 	mu_run_test (test_anal_get_base_type_union);
346 	mu_run_test (test_anal_save_base_type_union);
347 	mu_run_test (test_anal_get_base_type_enum);
348 	mu_run_test (test_anal_save_base_type_enum);
349 	mu_run_test (test_anal_get_base_type_typedef);
350 	mu_run_test (test_anal_save_base_type_typedef);
351 	mu_run_test (test_anal_get_base_type_atomic);
352 	mu_run_test (test_anal_save_base_type_atomic);
353 	mu_run_test (test_anal_get_base_type_not_found);
354 	return tests_passed != tests_run;
355 }
356 
main(int argc,char ** argv)357 int main(int argc, char **argv) {
358 	return all_tests();
359 }
360