mirror of
https://github.com/samba-team/samba.git
synced 2025-03-11 16:58:40 +03:00
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 commit is contained in:
parent
d2eb1a6844
commit
837c83d77a
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user