diff options
-rw-r--r-- | source4/librpc/ndr/libndr.h | 1 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_basic.c | 9 | ||||
-rw-r--r-- | source4/pidl/tests/Util.pm | 4 | ||||
-rwxr-xr-x | source4/pidl/tests/ndr_fullptr.pl | 41 |
4 files changed, 51 insertions, 4 deletions
diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h index 1076936c1d..fb151e4120 100644 --- a/source4/librpc/ndr/libndr.h +++ b/source4/librpc/ndr/libndr.h @@ -88,6 +88,7 @@ struct ndr_push { struct ndr_token_list *switch_list; struct ndr_token_list *relative_list; struct ndr_token_list *nbt_string_list; + struct ndr_token_list *full_ptr_list; /* this is used to ensure we generate unique reference IDs */ uint32_t ptr_count; diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c index b8f2a8115f..a9cfb558f7 100644 --- a/source4/librpc/ndr/ndr_basic.c +++ b/source4/librpc/ndr/ndr_basic.c @@ -485,8 +485,13 @@ _PUBLIC_ NTSTATUS ndr_push_full_ptr(struct ndr_push *ndr, const void *p) { uint32_t ptr = 0; if (p) { - ndr->ptr_count++; - ptr = ndr->ptr_count; + /* Check if the pointer already exists and has an id */ + ptr = ndr_token_peek(&ndr->full_ptr_list, p); + if (ptr == 0) { + ndr->ptr_count++; + ptr = ndr->ptr_count; + ndr_token_store(ndr, &ndr->full_ptr_list, p, ptr); + } } return ndr_push_uint32(ndr, NDR_SCALARS, ptr); } diff --git a/source4/pidl/tests/Util.pm b/source4/pidl/tests/Util.pm index ccac1a6d7e..e0d87b2dac 100644 --- a/source4/pidl/tests/Util.pm +++ b/source4/pidl/tests/Util.pm @@ -35,7 +35,7 @@ sub test_samba4_ndr SKIP: { skip "no samba environment available, skipping compilation", 3 - if (system("pkg-config --exists dcerpc ndr") != 0); + if (system("pkg-config --exists ndr") != 0); my $test_data_prefix = $ENV{TEST_DATA_PREFIX}; @@ -46,7 +46,7 @@ SKIP: { $outfile = "test-$name"; } - my $cflags = `pkg-config --libs --cflags dcerpc ndr`; + my $cflags = `pkg-config --libs --cflags ndr`; open CC, "|cc -x c - -o $outfile $cflags"; print CC "#define uint_t unsigned int\n"; diff --git a/source4/pidl/tests/ndr_fullptr.pl b/source4/pidl/tests/ndr_fullptr.pl new file mode 100755 index 0000000000..d9f2cd6b02 --- /dev/null +++ b/source4/pidl/tests/ndr_fullptr.pl @@ -0,0 +1,41 @@ +#!/usr/bin/perl +# Simple tests for unique pointers +# (C) 2006 Jelmer Vernooij <jelmer@samba.org>. +# Published under the GNU General Public License. +use strict; + +use Test::More tests => 1 * 8; +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; +use lib "$RealBin"; +use Util qw(test_samba4_ndr); + +test_samba4_ndr("fullptr-push-dup", +' + [public] uint16 echo_TestFull([in,ptr] uint32 *x, [in,ptr] uint32 *y); +', +' + struct ndr_push *ndr = ndr_push_init(); + uint32_t v = 13; + struct echo_TestRef r; + r.in.x = &v; + r.in.y = &v; + + if (NT_STATUS_IS_ERR(ndr_push_echo_TestRef(ndr, NDR_IN, &r))) { + fprintf(stderr, "push failed\n"); + return 1; + } + + if (ndr->offset != 12) { + fprintf(stderr, "Offset(%d) != 12\n", ndr->offset); + return 2; + } + + if (ndr->data[0] != ndr->data[8] || + ndr->data[1] != ndr->data[9] || + ndr->data[2] != ndr->data[10] || + ndr->data[3] != ndr->data[11]) { + fprintf(stderr, "Data incorrect\n"); + return 3; + } +'); |