diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2005-06-02 13:21:11 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:17:25 -0500 |
commit | c56ddaf7efdd5744c3f1adb7e40b1db5cbe01523 (patch) | |
tree | 6c707436e36bc62be2a52a1aebc513766fbfd9dc /source4 | |
parent | 180b269ac6fdf89cb4953089cf0f5f1e84f76166 (diff) | |
download | samba-c56ddaf7efdd5744c3f1adb7e40b1db5cbe01523.tar.gz samba-c56ddaf7efdd5744c3f1adb7e40b1db5cbe01523.tar.bz2 samba-c56ddaf7efdd5744c3f1adb7e40b1db5cbe01523.zip |
r7195: - Fix echo pipe
- Don't allocate strings
- Give higher preference to the [out] part of variables when they
are being used by another [out] variable. Also make sure that
[in] variables never use [out] variables (i.e. switch_is() on an
[in] variable can no longer use an [out] variable).
(This used to be commit 837c83d77a2d1990419c4f3e343616daf8da5799)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/build/pidl/ndr_parser.pm | 44 | ||||
-rw-r--r-- | source4/rpc_server/echo/rpc_echo.c | 3 | ||||
-rw-r--r-- | source4/torture/rpc/echo.c | 9 |
3 files changed, 38 insertions, 18 deletions
diff --git a/source4/build/pidl/ndr_parser.pm b/source4/build/pidl/ndr_parser.pm index 6000043041..473aa94f13 100644 --- a/source4/build/pidl/ndr_parser.pm +++ b/source4/build/pidl/ndr_parser.pm @@ -208,7 +208,21 @@ sub GenerateStructEnv($) return \%env; } -sub GenerateFunctionEnv($) +sub GenerateFunctionInEnv($) +{ + my $fn = shift; + my %env; + + foreach my $e (@{$fn->{ELEMENTS}}) { + if (grep (/in/, @{$e->{DIRECTION}})) { + $env{$e->{NAME}} = "r->in.$e->{NAME}"; + } + } + + return \%env; +} + +sub GenerateFunctionOutEnv($) { my $fn = shift; my %env; @@ -216,8 +230,7 @@ sub GenerateFunctionEnv($) foreach my $e (@{$fn->{ELEMENTS}}) { if (grep (/out/, @{$e->{DIRECTION}})) { $env{$e->{NAME}} = "r->out.$e->{NAME}"; - } - if (grep (/in/, @{$e->{DIRECTION}})) { + } elsif (grep (/in/, @{$e->{DIRECTION}})) { $env{$e->{NAME}} = "r->in.$e->{NAME}"; } } @@ -1031,13 +1044,15 @@ sub ParsePtrPull($$$$) my $nl = Ndr::GetNextLevel($e, $l); my $next_is_array = ($nl->{TYPE} eq "ARRAY"); + my $next_is_string = (($nl->{TYPE} eq "DATA") and + ($nl->{DATA_TYPE} eq "string")); if ($l->{POINTER_TYPE} eq "ref") { unless ($l->{LEVEL} eq "TOP") { pidl "NDR_CHECK(ndr_pull_ref_ptr($ndr, &_ptr_$e->{NAME}));"; } - unless ($next_is_array) { + unless ($next_is_array or $next_is_string) { pidl "if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {"; pidl "\tNDR_ALLOC($ndr, $var_name);"; pidl "}"; @@ -1052,7 +1067,7 @@ sub ParsePtrPull($$$$) # Don't do this for arrays, they're allocated at the actual level # of the array - unless ($next_is_array) { + unless ($next_is_array or $next_is_string) { pidl "NDR_ALLOC($ndr, $var_name);"; } else { pidl "NDR_ALLOC_SIZE($ndr, $var_name, 1);"; # FIXME: Yes, this is nasty. We allocate an array twice - once just to indicate that it's there, then the real allocation... @@ -1861,8 +1876,6 @@ sub ParseFunctionPrint($) return if util::has_property($fn, "noprint"); - my $env = GenerateFunctionEnv($fn); - pidl "void ndr_print_$fn->{NAME}(struct ndr_print *ndr, const char *name, int flags, struct $fn->{NAME} *r)"; pidl "{"; indent; @@ -1883,6 +1896,8 @@ sub ParseFunctionPrint($) pidl "ndr_print_struct(ndr, \"in\", \"$fn->{NAME}\");"; pidl "ndr->depth++;"; + my $env = GenerateFunctionInEnv($fn); + foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/in/,@{$e->{DIRECTION}})) { ParseElementPrint($e, "r->in.$e->{NAME}", $env); @@ -1896,6 +1911,8 @@ sub ParseFunctionPrint($) indent; pidl "ndr_print_struct(ndr, \"out\", \"$fn->{NAME}\");"; pidl "ndr->depth++;"; + + $env = GenerateFunctionOutEnv($fn); foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/out/,@{$e->{DIRECTION}})) { ParseElementPrint($e, "r->out.$e->{NAME}", $env); @@ -1922,8 +1939,6 @@ sub ParseFunctionPush($) return if util::has_property($fn, "nopush"); - my $env = GenerateFunctionEnv($fn); - pidl fn_prefix($fn) . "NTSTATUS ndr_push_$fn->{NAME}(struct ndr_push *ndr, int flags, struct $fn->{NAME} *r)"; pidl "{"; indent; @@ -1935,6 +1950,8 @@ sub ParseFunctionPush($) pidl "if (flags & NDR_IN) {"; indent; + my $env = GenerateFunctionInEnv($fn); + foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/in/,@{$e->{DIRECTION}})) { ParseElementPush($e, "ndr", "r->in.", $env, 1, 1); @@ -1947,6 +1964,7 @@ sub ParseFunctionPush($) pidl "if (flags & NDR_OUT) {"; indent; + $env = GenerateFunctionOutEnv($fn); foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/out/,@{$e->{DIRECTION}})) { ParseElementPush($e, "ndr", "r->out.", $env, 1, 1); @@ -2001,8 +2019,6 @@ sub ParseFunctionPull($) return if util::has_property($fn, "nopull"); - my $env = GenerateFunctionEnv($fn); - # pull function args pidl fn_prefix($fn) . "NTSTATUS ndr_pull_$fn->{NAME}(struct ndr_pull *ndr, int flags, struct $fn->{NAME} *r)"; pidl "{"; @@ -2028,6 +2044,8 @@ sub ParseFunctionPull($) last; } + my $env = GenerateFunctionInEnv($fn); + foreach my $e (@{$fn->{ELEMENTS}}) { next unless (grep(/in/, @{$e->{DIRECTION}})); ParseElementPull($e, "ndr", "r->in.", $env, 1, 1); @@ -2040,7 +2058,8 @@ sub ParseFunctionPull($) next unless (grep(/out/, @{$e->{DIRECTION}})); next unless ($e->{LEVELS}[0]->{TYPE} eq "POINTER" and $e->{LEVELS}[0]->{POINTER_TYPE} eq "ref"); - + next if (($e->{LEVELS}[1]->{TYPE} eq "DATA") and + ($e->{LEVELS}[1]->{DATA_TYPE} eq "string")); if ($e->{LEVELS}[1]->{TYPE} eq "ARRAY") { my $size = ParseExpr($e->{LEVELS}[1]->{SIZE_IS}, $env); @@ -2070,6 +2089,7 @@ sub ParseFunctionPull($) pidl "if (flags & NDR_OUT) {"; indent; + $env = GenerateFunctionOutEnv($fn); foreach my $e (@{$fn->{ELEMENTS}}) { next unless grep(/out/, @{$e->{DIRECTION}}); ParseElementPull($e, "ndr", "r->out.", $env, 1, 1); diff --git a/source4/rpc_server/echo/rpc_echo.c b/source4/rpc_server/echo/rpc_echo.c index 057d89a866..b67c172579 100644 --- a/source4/rpc_server/echo/rpc_echo.c +++ b/source4/rpc_server/echo/rpc_echo.c @@ -56,6 +56,9 @@ static NTSTATUS echo_SinkData(struct dcesrv_call_state *dce_call, TALLOC_CTX *me static NTSTATUS echo_SourceData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct echo_SourceData *r) { int i; + + r->out.data = talloc_array(mem_ctx, uint8_t, r->in.len); + for (i=0;i<r->in.len;i++) { r->out.data[i] = i; } diff --git a/source4/torture/rpc/echo.c b/source4/torture/rpc/echo.c index 14bfe573ce..96a716a312 100644 --- a/source4/torture/rpc/echo.c +++ b/source4/torture/rpc/echo.c @@ -107,15 +107,11 @@ static BOOL test_sourcedata(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) int i; NTSTATUS status; int len = 200000 + (random() % 5000); - uint8_t *data_out; struct echo_SourceData r; printf("\nTesting SourceData\n"); - data_out = talloc_size(mem_ctx, len); - r.in.len = len; - r.out.data = data_out; status = dcerpc_echo_SourceData(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -124,9 +120,9 @@ static BOOL test_sourcedata(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) } for (i=0;i<len;i++) { - uint8_t *v = (uint8_t *)data_out; + uint8_t *v = (uint8_t *)r.out.data; if (v[i] != (i & 0xFF)) { - printf("bad data 0x%x at %d\n", (uint8_t)data_out[i], i); + printf("bad data 0x%x at %d\n", (uint8_t)r.out.data[i], i); return False; } } @@ -199,6 +195,7 @@ static BOOL test_testcall2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) for (i=1;i<=7;i++) { r.in.level = i; + r.out.info = talloc(mem_ctx, union echo_Info); printf("\nTesting TestCall2 level %d\n", i); status = dcerpc_echo_TestCall2(p, mem_ctx, &r); |