1#!/usr/bin/perl
2# Simple tests for pidl's handling of ref pointers, based
3# on tridge's ref_notes.txt
4# (C) 2005 Jelmer Vernooij <jelmer@samba.org>.
5# Published under the GNU General Public License.
6use strict;
7
8use Test::More tests => 22 * 8;
9use FindBin qw($RealBin);
10use lib "$RealBin";
11use Util qw(test_samba4_ndr);
12
13test_samba4_ndr("noptr-push",
14'	typedef struct {
15		uint16 x;
16	} xstruct;
17
18	[public] uint16 echo_TestRef([in] xstruct foo);
19',
20'
21	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
22	uint16_t v = 13;
23	struct echo_TestRef r;
24	r.in.foo.x = v;
25
26	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r))) {
27		fprintf(stderr, "push failed\n");
28		return 1;
29	}
30
31	if (ndr->offset != 2) {
32		fprintf(stderr, "Offset(%d) != 2\n", ndr->offset);
33		return 2;
34	}
35
36	if (ndr->data[0] != 13 || ndr->data[1] != 0) {
37		fprintf(stderr, "Data incorrect\n");
38		return 3;
39	}
40');
41
42test_samba4_ndr("ptr-embedded-push",
43'   typedef struct {
44		uint16 *x;
45	} xstruct;
46
47	[public] uint16 echo_TestRef([in] xstruct foo);
48',
49'
50	uint16_t v = 13;
51	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
52	struct echo_TestRef r;
53	r.in.foo.x = &v;
54
55	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
56		return 1;
57
58	if (ndr->offset != 6)
59		return 2;
60
61	if (ndr->data[0] == 0 && ndr->data[1] == 0 &&
62	    ndr->data[2] == 0 && ndr->data[3] == 0)
63		return 3;
64
65	if (ndr->data[4] != 13 || ndr->data[5] != 0)
66		return 4;
67');
68
69test_samba4_ndr("ptr-embedded-push-null",
70'   typedef struct {
71		uint16 *x;
72	} xstruct;
73
74	[public] uint16 echo_TestRef([in] xstruct foo);
75',
76'
77	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
78	struct echo_TestRef r;
79	r.in.foo.x = NULL;
80
81	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
82		return 1;
83
84	if (ndr->offset != 4)
85		return 2;
86
87	if (ndr->data[0] != 0 || ndr->data[1] != 0 ||
88	    ndr->data[2] != 0 || ndr->data[3] != 0)
89		return 3;
90');
91
92test_samba4_ndr("refptr-embedded-push",
93'
94	typedef struct {
95		[ref] uint16 *x;
96	} xstruct;
97
98	[public] uint16 echo_TestRef([in] xstruct foo);
99',
100'
101	uint16_t v = 13;
102	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
103	struct echo_TestRef r;
104	r.in.foo.x = &v;
105
106	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
107		return 1;
108
109	if (ndr->offset != 6)
110		return 2;
111
112	if (ndr->data[0] == 0 && ndr->data[1] == 0 &&
113	    ndr->data[2] == 0 && ndr->data[3] == 0)
114		return 3;
115
116	if (ndr->data[4] != 13 || ndr->data[5] != 0)
117		return 4;
118');
119
120test_samba4_ndr("refptr-embedded-push-null",
121'
122	typedef struct {
123		[ref] uint16 *x;
124	} xstruct;
125
126	[public] uint16 echo_TestRef([in] xstruct foo);
127',
128'
129	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
130	struct echo_TestRef r;
131	r.in.foo.x = NULL;
132
133	if (NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
134		return 1;
135	/* Windows gives [client runtime error 0x6f4] */
136');
137
138test_samba4_ndr("ptr-top-push",
139'
140	typedef struct {
141		uint16 x;
142	} xstruct;
143
144	[public] uint16 echo_TestRef([in] xstruct *foo);
145',
146'
147	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
148	struct echo_TestRef r;
149	struct xstruct s;
150	s.x = 13;
151	r.in.foo = &s;
152
153	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
154		return 1;
155
156	if (ndr->offset != 2)
157		return 2;
158
159	if (ndr->data[0] != 13 || ndr->data[1] != 0)
160		return 3;
161');
162
163test_samba4_ndr("ptr-top-push-null",
164'
165	typedef struct {
166		uint16 x;
167	} xstruct;
168
169	[public] uint16 echo_TestRef([in] xstruct *foo);
170',
171'
172	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
173	struct echo_TestRef r;
174	r.in.foo = NULL;
175
176	if (NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
177		return 1;
178
179	/* Windows gives [client runtime error 0x6f4] */
180');
181
182
183test_samba4_ndr("refptr-top-push",
184'
185	typedef struct {
186		uint16 x;
187	} xstruct;
188
189	[public] uint16 echo_TestRef([in,ref] xstruct *foo);
190',
191'
192	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
193	struct echo_TestRef r;
194	struct xstruct s;
195	s.x = 13;
196	r.in.foo = &s;
197
198	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
199		return 1;
200
201	if (ndr->offset != 2)
202		return 2;
203
204	if (ndr->data[0] != 13 || ndr->data[1] != 0)
205		return 3;
206');
207
208test_samba4_ndr("refptr-top-push-null",
209'
210	typedef struct {
211		uint16 x;
212	} xstruct;
213
214	[public] uint16 echo_TestRef([in,ref] xstruct *foo);
215',
216'
217	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
218	struct echo_TestRef r;
219	r.in.foo = NULL;
220
221	if (NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
222		return 1;
223
224	/* Windows gives [client runtime error 0x6f4] */
225');
226
227
228test_samba4_ndr("uniqueptr-top-push",
229'	typedef struct {
230		uint16 x;
231	} xstruct;
232
233	[public] uint16 echo_TestRef([in,unique] xstruct *foo);
234',
235'
236	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
237	struct echo_TestRef r;
238	struct xstruct s;
239	s.x = 13;
240	r.in.foo = &s;
241
242	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
243		return 1;
244
245	if (ndr->offset != 6)
246		return 2;
247
248	if (ndr->data[0] == 0 && ndr->data[1] == 0 &&
249	    ndr->data[2] == 0 && ndr->data[3] == 0)
250		return 3;
251
252	if (ndr->data[4] != 13 || ndr->data[5] != 0)
253		return 4;
254');
255
256test_samba4_ndr("uniqueptr-top-push-null",
257'	typedef struct {
258		uint16 x;
259	} xstruct;
260
261	[public] uint16 echo_TestRef([in,unique] xstruct *foo);
262',
263'
264	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
265	struct echo_TestRef r;
266	r.in.foo = NULL;
267
268	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
269		return 1;
270
271	if (ndr->offset != 4)
272		return 2;
273
274	if (ndr->data[0] != 0 || ndr->data[1] != 0 ||
275	    ndr->data[2] != 0 || ndr->data[3] != 0)
276		return 3;
277');
278
279
280test_samba4_ndr("ptr-top-out-pull",
281'
282	typedef struct {
283		uint16 x;
284	} xstruct;
285
286	[public] void echo_TestRef([out] xstruct *foo);
287',
288'
289	uint8_t data[] = { 0x0D, 0x00 };
290	DATA_BLOB b = { data, 2 };
291	struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL);
292	struct xstruct s;
293	struct echo_TestRef r;
294
295	r.out.foo = &s;
296
297	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_echo_TestRef(ndr, NDR_OUT, &r)))
298		return 1;
299
300	if (!r.out.foo)
301		return 2;
302
303	if (r.out.foo->x != 13)
304		return 3;
305');
306
307test_samba4_ndr("ptr-top-out-pull-null",
308'
309	typedef struct {
310		uint16 x;
311	} xstruct;
312
313	[public] void echo_TestRef([out] xstruct *foo);
314',
315'
316	uint8_t data[] = { 0x0D, 0x00 };
317	DATA_BLOB b = { data, 2 };
318	struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL);
319	struct echo_TestRef r;
320
321	r.out.foo = NULL;
322
323	if (NDR_ERR_CODE_IS_SUCCESS(ndr_pull_echo_TestRef(ndr, NDR_OUT, &r)))
324		return 1;
325
326	/* Windows gives [client runtime error 0x6f4] */
327');
328
329
330test_samba4_ndr("refptr-top-out-pull",
331'
332	typedef struct {
333		uint16 x;
334	} xstruct;
335
336	[public] void echo_TestRef([out,ref] xstruct *foo);
337',
338'
339	uint8_t data[] = { 0x0D, 0x00 };
340	DATA_BLOB b = { data, 2 };
341	struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL);
342	struct xstruct s;
343	struct echo_TestRef r;
344
345	r.out.foo = &s;
346
347	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_echo_TestRef(ndr, NDR_OUT, &r)))
348		return 1;
349
350	if (!r.out.foo)
351		return 2;
352
353	if (r.out.foo->x != 13)
354		return 3;
355');
356
357test_samba4_ndr("refptr-top-out-pull-null",
358'
359	typedef struct {
360		uint16 x;
361	} xstruct;
362
363	[public] void echo_TestRef([out,ref] xstruct *foo);
364',
365'
366	uint8_t data[] = { 0x0D, 0x00 };
367	DATA_BLOB b = { data, 2 };
368	struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL);
369	struct echo_TestRef r;
370
371	r.out.foo = NULL;
372
373	if (NDR_ERR_CODE_IS_SUCCESS(ndr_pull_echo_TestRef(ndr, NDR_OUT, &r)))
374		return 1;
375
376	/* Windows gives [client runtime error 0x6f4] */
377');
378
379
380test_samba4_ndr("ptr-top-push-double",
381'
382	[public] void echo_TestRef([in] uint16 **foo);
383',
384'	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
385	struct echo_TestRef r;
386	uint16_t v = 13;
387	uint16_t *pv = &v;
388	r.in.foo = &pv;
389
390	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
391		return 1;
392
393	if (ndr->offset != 6)
394		return 2;
395
396	if (ndr->data[0] == 0 && ndr->data[1] == 0 &&
397	    ndr->data[2] == 0 && ndr->data[3] == 0)
398		return 3;
399
400	if (ndr->data[4] != 0x0D || ndr->data[5] != 0x00)
401		return 4;
402');
403
404SKIP: {
405	skip "ptr-top-push-double-sndnull is known to fail", 8;
406
407test_samba4_ndr("ptr-top-push-double-sndnull",
408'
409	[public] void echo_TestRef([in] uint16 **foo);
410',
411'	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
412	struct echo_TestRef r;
413	uint16_t *pv = NULL;
414	r.in.foo = &pv;
415
416	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
417		return 1;
418
419	if (ndr->offset != 4)
420		return 2;
421
422	if (ndr->data[0] != 0 || ndr->data[1] != 0 ||
423	    ndr->data[2] != 0 || ndr->data[3] != 0)
424		return 3;
425');
426}
427
428test_samba4_ndr("ptr-top-push-double-fstnull",
429'
430	[public] void echo_TestRef([in] uint16 **foo);
431',
432'	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
433	struct echo_TestRef r;
434	r.in.foo = NULL;
435
436	if (NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
437		return 1;
438
439	/* Windows gives [client runtime error 0x6f4] */
440
441');
442
443
444test_samba4_ndr("refptr-top-push-double",
445'
446	[public] void echo_TestRef([in,ref] uint16 **foo);
447',
448'	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
449	struct echo_TestRef r;
450	uint16_t v = 13;
451	uint16_t *pv = &v;
452	r.in.foo = &pv;
453
454	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
455		return 1;
456
457	if (ndr->offset != 6)
458		return 2;
459
460	if (ndr->data[0] == 0 && ndr->data[1] == 0 &&
461	    ndr->data[2] == 0 && ndr->data[3] == 0)
462		return 3;
463
464	if (ndr->data[4] != 0x0D || ndr->data[5] != 0x00)
465		return 4;
466');
467
468SKIP: {
469
470	skip "refptr-top-push-double-sndnull is known to fail", 8;
471
472test_samba4_ndr("refptr-top-push-double-sndnull",
473'
474	[public] void echo_TestRef([in,ref] uint16 **foo);
475',
476'	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
477	struct echo_TestRef r;
478	uint16_t *pv = NULL;
479	r.in.foo = &pv;
480
481	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
482		return 1;
483
484	if (ndr->offset != 4)
485		return 2;
486
487	if (ndr->data[0] != 0 || ndr->data[1] != 0 ||
488	    ndr->data[2] != 0 || ndr->data[3] != 0)
489		return 3;
490');
491}
492
493test_samba4_ndr("refptr-top-push-double-fstnull",
494'
495	[public] void echo_TestRef([in,ref] uint16 **foo);
496',
497'	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
498	struct echo_TestRef r;
499	r.in.foo = NULL;
500
501	if (NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
502		return 1;
503
504	/* Windows gives [client runtime error 0x6f4] */
505
506');
507
508SKIP: {
509	skip "ignore-ptrs are not supported yet", 8;
510test_samba4_ndr("ignore-ptr",
511'
512	[public] void echo_TestRef([in,ignore] uint16 *foo, [in] uint16 *bar);
513',
514'	struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
515	struct echo_TestRef r;
516	uint16_t v = 10;
517	r.in.foo = &v;
518	r.in.bar = &v;
519
520	if (NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
521		return 1;
522
523	if (ndr->offset != 4)
524		return 2;
525');
526}
527