Fix bug 8920, null dereference
[Samba/gebeck_regimport.git] / pidl / tests / ndr.pl
blobb6fd4899b013367ec9409f60717e82fee64fc80f
1 #!/usr/bin/perl
2 # (C) 2007 Jelmer Vernooij <jelmer@samba.org>
3 # Published under the GNU General Public License
4 use strict;
5 use warnings;
7 use Test::More tests => 47;
8 use FindBin qw($RealBin);
9 use lib "$RealBin";
10 use Util;
11 use Parse::Pidl::Util qw(MyDumper);
12 use Parse::Pidl::NDR qw(GetElementLevelTable ParseElement align_type mapToScalar ParseType can_contain_deferred);
14 # Case 1
16 my $e = {
17 'FILE' => 'foo.idl',
18 'NAME' => 'v',
19 'PROPERTIES' => {},
20 'POINTERS' => 0,
21 'TYPE' => 'uint8',
22 'PARENT' => { TYPE => 'STRUCT' },
23 'LINE' => 42 };
25 is_deeply(GetElementLevelTable($e, "unique", 0), [
27 'IS_DEFERRED' => 0,
28 'LEVEL_INDEX' => 0,
29 'DATA_TYPE' => 'uint8',
30 'CONTAINS_DEFERRED' => 0,
31 'TYPE' => 'DATA',
32 'IS_SURROUNDING' => 0,
34 ]);
36 my $ne = ParseElement($e, "unique", 0);
37 is($ne->{ORIGINAL}, $e);
38 is($ne->{NAME}, "v");
39 is($ne->{ALIGN}, 1);
40 is($ne->{TYPE}, "uint8");
41 is_deeply($ne->{LEVELS}, [
43 'IS_DEFERRED' => 0,
44 'LEVEL_INDEX' => 0,
45 'DATA_TYPE' => 'uint8',
46 'CONTAINS_DEFERRED' => 0,
47 'TYPE' => 'DATA',
48 'IS_SURROUNDING' => 0,
50 ]);
52 # Case 2 : pointers
54 $e = {
55 'FILE' => 'foo.idl',
56 'NAME' => 'v',
57 'PROPERTIES' => {"unique" => 1},
58 'POINTERS' => 1,
59 'PARENT' => { TYPE => 'STRUCT' },
60 'TYPE' => 'uint8',
61 'LINE' => 42 };
63 is_deeply(GetElementLevelTable($e, "unique", 0), [
65 LEVEL_INDEX => 0,
66 IS_DEFERRED => 0,
67 TYPE => 'POINTER',
68 POINTER_TYPE => "unique",
69 POINTER_INDEX => 0,
70 LEVEL => 'EMBEDDED'
73 'IS_DEFERRED' => 1,
74 'LEVEL_INDEX' => 1,
75 'DATA_TYPE' => 'uint8',
76 'CONTAINS_DEFERRED' => 0,
77 'TYPE' => 'DATA',
78 'IS_SURROUNDING' => 0,
80 ]);
82 # Case 3 : double pointers
84 $e = {
85 'FILE' => 'foo.idl',
86 'NAME' => 'v',
87 'PROPERTIES' => {"unique" => 1},
88 'POINTERS' => 2,
89 'TYPE' => 'uint8',
90 'PARENT' => { TYPE => 'STRUCT' },
91 'LINE' => 42 };
93 is_deeply(GetElementLevelTable($e, "unique", 0), [
95 LEVEL_INDEX => 0,
96 IS_DEFERRED => 0,
97 TYPE => 'POINTER',
98 POINTER_TYPE => "unique",
99 POINTER_INDEX => 0,
100 LEVEL => 'EMBEDDED'
103 LEVEL_INDEX => 1,
104 IS_DEFERRED => 1,
105 TYPE => 'POINTER',
106 POINTER_TYPE => "unique",
107 POINTER_INDEX => 1,
108 LEVEL => 'EMBEDDED'
111 'IS_DEFERRED' => 1,
112 'LEVEL_INDEX' => 2,
113 'DATA_TYPE' => 'uint8',
114 'CONTAINS_DEFERRED' => 0,
115 'TYPE' => 'DATA',
116 'IS_SURROUNDING' => 0,
120 # Case 3 : ref pointers
122 $e = {
123 'FILE' => 'foo.idl',
124 'NAME' => 'v',
125 'PROPERTIES' => {"ref" => 1},
126 'POINTERS' => 1,
127 'TYPE' => 'uint8',
128 'PARENT' => { TYPE => 'STRUCT' },
129 'LINE' => 42 };
131 is_deeply(GetElementLevelTable($e, "unique", 0), [
133 LEVEL_INDEX => 0,
134 IS_DEFERRED => 0,
135 TYPE => 'POINTER',
136 POINTER_TYPE => "ref",
137 POINTER_INDEX => 0,
138 LEVEL => 'EMBEDDED'
141 'IS_DEFERRED' => 1,
142 'LEVEL_INDEX' => 1,
143 'DATA_TYPE' => 'uint8',
144 'CONTAINS_DEFERRED' => 0,
145 'TYPE' => 'DATA',
146 'IS_SURROUNDING' => 0,
150 # Case 3 : ref pointers
152 $e = {
153 'FILE' => 'foo.idl',
154 'NAME' => 'v',
155 'PROPERTIES' => {"ref" => 1},
156 'POINTERS' => 3,
157 'TYPE' => 'uint8',
158 'PARENT' => { TYPE => 'STRUCT' },
159 'LINE' => 42 };
161 is_deeply(GetElementLevelTable($e, "unique", 0), [
163 LEVEL_INDEX => 0,
164 IS_DEFERRED => 0,
165 TYPE => 'POINTER',
166 POINTER_TYPE => "ref",
167 POINTER_INDEX => 0,
168 LEVEL => 'EMBEDDED'
171 LEVEL_INDEX => 1,
172 IS_DEFERRED => 1,
173 TYPE => 'POINTER',
174 POINTER_TYPE => "unique",
175 POINTER_INDEX => 1,
176 LEVEL => 'EMBEDDED'
179 LEVEL_INDEX => 2,
180 IS_DEFERRED => 1,
181 TYPE => 'POINTER',
182 POINTER_TYPE => "unique",
183 POINTER_INDEX => 2,
184 LEVEL => 'EMBEDDED'
187 'IS_DEFERRED' => 1,
188 'LEVEL_INDEX' => 3,
189 'DATA_TYPE' => 'uint8',
190 'CONTAINS_DEFERRED' => 0,
191 'TYPE' => 'DATA',
192 'IS_SURROUNDING' => 0,
196 # Case 3 : ref pointers
198 $e = {
199 'FILE' => 'foo.idl',
200 'NAME' => 'v',
201 'PROPERTIES' => {"ref" => 1},
202 'POINTERS' => 3,
203 'TYPE' => 'uint8',
204 'PARENT' => { TYPE => 'STRUCT' },
205 'LINE' => 42 };
207 is_deeply(GetElementLevelTable($e, "ref", 0), [
209 LEVEL_INDEX => 0,
210 IS_DEFERRED => 0,
211 TYPE => 'POINTER',
212 POINTER_TYPE => "ref",
213 POINTER_INDEX => 0,
214 LEVEL => 'EMBEDDED'
217 LEVEL_INDEX => 1,
218 IS_DEFERRED => 1,
219 TYPE => 'POINTER',
220 POINTER_TYPE => "ref",
221 POINTER_INDEX => 1,
222 LEVEL => 'EMBEDDED'
225 LEVEL_INDEX => 2,
226 IS_DEFERRED => 1,
227 TYPE => 'POINTER',
228 POINTER_TYPE => "ref",
229 POINTER_INDEX => 2,
230 LEVEL => 'EMBEDDED'
233 'IS_DEFERRED' => 1,
234 'LEVEL_INDEX' => 3,
235 'DATA_TYPE' => 'uint8',
236 'CONTAINS_DEFERRED' => 0,
237 'TYPE' => 'DATA',
238 'IS_SURROUNDING' => 0,
242 # Case 4 : top-level ref pointers
244 $e = {
245 'FILE' => 'foo.idl',
246 'NAME' => 'v',
247 'PROPERTIES' => {"ref" => 1},
248 'POINTERS' => 1,
249 'TYPE' => 'uint8',
250 'PARENT' => { TYPE => 'FUNCTION' },
251 'LINE' => 42 };
253 is_deeply(GetElementLevelTable($e, "unique", 0), [
255 LEVEL_INDEX => 0,
256 IS_DEFERRED => 0,
257 TYPE => 'POINTER',
258 POINTER_TYPE => "ref",
259 POINTER_INDEX => 0,
260 LEVEL => 'TOP'
263 'IS_DEFERRED' => 0,
264 'LEVEL_INDEX' => 1,
265 'DATA_TYPE' => 'uint8',
266 'CONTAINS_DEFERRED' => 0,
267 'TYPE' => 'DATA',
268 'IS_SURROUNDING' => 0,
272 # Case 4 : top-level ref pointers, triple with pointer_default("unique")
274 $e = {
275 'FILE' => 'foo.idl',
276 'NAME' => 'v',
277 'PROPERTIES' => {"ref" => 1},
278 'POINTERS' => 3,
279 'TYPE' => 'uint8',
280 'PARENT' => { TYPE => 'FUNCTION' },
281 'LINE' => 42 };
283 is_deeply(GetElementLevelTable($e, "unique", 0), [
285 LEVEL_INDEX => 0,
286 IS_DEFERRED => 0,
287 TYPE => 'POINTER',
288 POINTER_TYPE => "ref",
289 POINTER_INDEX => 0,
290 LEVEL => 'TOP'
293 LEVEL_INDEX => 1,
294 IS_DEFERRED => 0,
295 TYPE => 'POINTER',
296 POINTER_TYPE => "unique",
297 POINTER_INDEX => 1,
298 LEVEL => 'EMBEDDED'
301 LEVEL_INDEX => 2,
302 IS_DEFERRED => 1,
303 TYPE => 'POINTER',
304 POINTER_TYPE => "unique",
305 POINTER_INDEX => 2,
306 LEVEL => 'EMBEDDED'
309 'IS_DEFERRED' => 1,
310 'LEVEL_INDEX' => 3,
311 'DATA_TYPE' => 'uint8',
312 'CONTAINS_DEFERRED' => 0,
313 'TYPE' => 'DATA',
314 'IS_SURROUNDING' => 0,
318 # Case 4 : top-level unique pointers, triple with pointer_default("unique")
320 $e = {
321 'FILE' => 'foo.idl',
322 'NAME' => 'v',
323 'PROPERTIES' => {"unique" => 1, "in" => 1},
324 'POINTERS' => 3,
325 'TYPE' => 'uint8',
326 'PARENT' => { TYPE => 'FUNCTION' },
327 'LINE' => 42 };
329 is_deeply(GetElementLevelTable($e, "unique", 0), [
331 LEVEL_INDEX => 0,
332 IS_DEFERRED => 0,
333 TYPE => 'POINTER',
334 POINTER_TYPE => "unique",
335 POINTER_INDEX => 0,
336 LEVEL => 'TOP'
339 LEVEL_INDEX => 1,
340 IS_DEFERRED => 1,
341 TYPE => 'POINTER',
342 POINTER_TYPE => "unique",
343 POINTER_INDEX => 1,
344 LEVEL => 'EMBEDDED'
347 LEVEL_INDEX => 2,
348 IS_DEFERRED => 1,
349 TYPE => 'POINTER',
350 POINTER_TYPE => "unique",
351 POINTER_INDEX => 2,
352 LEVEL => 'EMBEDDED'
355 'IS_DEFERRED' => 1,
356 'LEVEL_INDEX' => 3,
357 'DATA_TYPE' => 'uint8',
358 'CONTAINS_DEFERRED' => 0,
359 'TYPE' => 'DATA',
360 'IS_SURROUNDING' => 0,
364 # Case 4 : top-level unique pointers, triple with pointer_default("ref")
366 $e = {
367 'FILE' => 'foo.idl',
368 'NAME' => 'v',
369 'PROPERTIES' => {"unique" => 1, "in" => 1},
370 'POINTERS' => 3,
371 'TYPE' => 'uint8',
372 'PARENT' => { TYPE => 'FUNCTION' },
373 'LINE' => 42 };
375 is_deeply(GetElementLevelTable($e, "ref", 0), [
377 LEVEL_INDEX => 0,
378 IS_DEFERRED => 0,
379 TYPE => 'POINTER',
380 POINTER_TYPE => "unique",
381 POINTER_INDEX => 0,
382 LEVEL => 'TOP'
385 LEVEL_INDEX => 1,
386 IS_DEFERRED => 1,
387 TYPE => 'POINTER',
388 POINTER_TYPE => "ref",
389 POINTER_INDEX => 1,
390 LEVEL => 'EMBEDDED'
393 LEVEL_INDEX => 2,
394 IS_DEFERRED => 1,
395 TYPE => 'POINTER',
396 POINTER_TYPE => "ref",
397 POINTER_INDEX => 2,
398 LEVEL => 'EMBEDDED'
401 'IS_DEFERRED' => 1,
402 'LEVEL_INDEX' => 3,
403 'DATA_TYPE' => 'uint8',
404 'CONTAINS_DEFERRED' => 0,
405 'TYPE' => 'DATA',
406 'IS_SURROUNDING' => 0,
410 # Case 4 : top-level ref pointers, triple with pointer_default("ref")
412 $e = {
413 'FILE' => 'foo.idl',
414 'NAME' => 'v',
415 'PROPERTIES' => {"ref" => 1},
416 'POINTERS' => 3,
417 'TYPE' => 'uint8',
418 'PARENT' => { TYPE => 'FUNCTION' },
419 'LINE' => 42 };
421 is_deeply(GetElementLevelTable($e, "ref", 0), [
423 LEVEL_INDEX => 0,
424 IS_DEFERRED => 0,
425 TYPE => 'POINTER',
426 POINTER_TYPE => "ref",
427 POINTER_INDEX => 0,
428 LEVEL => 'TOP'
431 LEVEL_INDEX => 1,
432 IS_DEFERRED => 0,
433 TYPE => 'POINTER',
434 POINTER_TYPE => "ref",
435 POINTER_INDEX => 1,
436 LEVEL => 'EMBEDDED'
439 LEVEL_INDEX => 2,
440 IS_DEFERRED => 1,
441 TYPE => 'POINTER',
442 POINTER_TYPE => "ref",
443 POINTER_INDEX => 2,
444 LEVEL => 'EMBEDDED'
447 'IS_DEFERRED' => 1,
448 'LEVEL_INDEX' => 3,
449 'DATA_TYPE' => 'uint8',
450 'CONTAINS_DEFERRED' => 0,
451 'TYPE' => 'DATA',
452 'IS_SURROUNDING' => 0,
456 # representation_type
457 $e = {
458 'FILE' => 'foo.idl',
459 'NAME' => 'v',
460 'PROPERTIES' => { represent_as => "bar" },
461 'POINTERS' => 0,
462 'TYPE' => 'uint8',
463 'PARENT' => { TYPE => 'STRUCT' },
464 'LINE' => 42 };
466 $ne = ParseElement($e, undef, 0);
467 is($ne->{REPRESENTATION_TYPE}, "bar");
469 # representation_type
470 $e = {
471 'FILE' => 'foo.idl',
472 'NAME' => 'v',
473 'PROPERTIES' => { },
474 'POINTERS' => 0,
475 'TYPE' => 'uint8',
476 'PARENT' => { TYPE => 'STRUCT' },
477 'LINE' => 42 };
479 $ne = ParseElement($e, undef, 0);
480 is($ne->{REPRESENTATION_TYPE}, "uint8");
482 is(align_type("hyper"), 8);
483 is(align_type("double"), 8);
484 is(align_type("uint32"), 4);
485 is(align_type("uint16"), 2);
486 is(align_type("uint8"), 1);
487 is(align_type({ TYPE => "STRUCT", "NAME" => "bla",
488 ELEMENTS => [ { TYPE => "uint16" } ] }), 4);
489 is(align_type({ TYPE => "STRUCT",
490 ELEMENTS => [ { TYPE => "hyper" } ] }), 8);
491 is(align_type({ TYPE => "TYPEDEF", DATA => {
492 TYPE => "STRUCT",
493 ELEMENTS => [ { TYPE => "hyper" } ] }}), 8);
494 # typedef of struct without body
495 is(align_type({ TYPE => "TYPEDEF", DATA => {
496 TYPE => "STRUCT", ELEMENTS => undef }}), 4);
497 # struct without body
498 is(align_type({ TYPE => "STRUCT", ELEMENTS => undef }), 4);
499 # empty struct
500 is(align_type({ TYPE => "STRUCT", ELEMENTS => [] }), 1);
501 is(align_type({ TYPE => "STRUCT", "NAME" => "bla",
502 ELEMENTS => [ { TYPE => "uint8" } ] }), 4);
504 is(mapToScalar("someverymuchnotexistingtype"), undef);
505 is(mapToScalar("uint32"), "uint32");
506 is(mapToScalar({TYPE => "ENUM", PARENT => { PROPERTIES => { enum8bit => 1 } } }), "uint8");
507 is(mapToScalar({TYPE => "BITMAP", PROPERTIES => { bitmap64bit => 1 } }),
508 "hyper");
509 is(mapToScalar({TYPE => "TYPEDEF", DATA => {TYPE => "ENUM", PARENT => { PROPERTIES => { enum8bit => 1 } } }}), "uint8");
511 my $t;
512 $t = {
513 TYPE => "STRUCT",
514 NAME => "foo",
515 SURROUNDING_ELEMENT => undef,
516 ELEMENTS => undef,
517 PROPERTIES => undef,
518 ORIGINAL => {
519 TYPE => "STRUCT",
520 NAME => "foo"
522 ALIGN => undef
524 is_deeply(ParseType($t->{ORIGINAL}, "ref", 0), $t);
526 $t = {
527 TYPE => "UNION",
528 NAME => "foo",
529 SWITCH_TYPE => "uint32",
530 ELEMENTS => undef,
531 PROPERTIES => undef,
532 HAS_DEFAULT => 0,
533 IS_MS_UNION => 0,
534 ORIGINAL => {
535 TYPE => "UNION",
536 NAME => "foo"
538 ALIGN => undef
540 is_deeply(ParseType($t->{ORIGINAL}, "ref", 0), $t);
542 ok(not can_contain_deferred("uint32"));
543 ok(can_contain_deferred("some_unknown_type"));
544 ok(can_contain_deferred({ TYPE => "STRUCT",
545 ELEMENTS => [ { TYPE => "uint32", POINTERS => 40 } ]}));
546 ok(can_contain_deferred({ TYPE => "TYPEDEF",
547 DATA => { TYPE => "STRUCT",
548 ELEMENTS => [ { TYPE => "uint32", POINTERS => 40 } ]}}));
549 ok(not can_contain_deferred({ TYPE => "STRUCT",
550 ELEMENTS => [ { TYPE => "uint32" } ]}));
551 ok(not can_contain_deferred({ TYPE => "TYPEDEF",
552 DATA => { TYPE => "STRUCT",
553 ELEMENTS => [ { TYPE => "uint32" } ]}}));
554 ok(can_contain_deferred({ TYPE => "STRUCT",
555 ELEMENTS => [ { TYPE => "someunknowntype" } ]}));
556 # Make sure the elements for a enum without body aren't filled in
557 ok(not defined(ParseType({TYPE => "ENUM", NAME => "foo" }, "ref", 0)->{ELEMENTS}));
558 # Make sure the elements for a bitmap without body aren't filled in
559 ok(not defined(ParseType({TYPE => "BITMAP", NAME => "foo" }, "ref", 0)->{ELEMENTS}));
560 # Make sure the elements for a union without body aren't filled in
561 ok(not defined(ParseType({TYPE => "UNION", NAME => "foo" }, "ref", 0)->{ELEMENTS}));