diff options
author | Samuel Cabrero <scabrero@suse.de> | 2019-03-11 14:10:28 +0100 |
---|---|---|
committer | Samuel Cabrero <scabrero@sn-devel-184> | 2020-03-20 15:36:35 +0000 |
commit | 73e32f5f42b13ef65aff79a203a99e6f2a99763d (patch) | |
tree | 6b39dc26d6e9aef6fce09d3df17b3f107752ca79 /pidl/lib | |
parent | bebd55784a1b85b4033e8fef8114b0d67025b223 (diff) | |
download | samba-73e32f5f42b13ef65aff79a203a99e6f2a99763d.tar.gz |
pidl:NDR/ServerCompat: Initialize and allocate out vars
Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'pidl/lib')
-rw-r--r-- | pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm | 111 |
1 files changed, 110 insertions, 1 deletions
diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm index fa5292e5aa9..47c810d1fbe 100644 --- a/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm +++ b/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm @@ -11,8 +11,12 @@ use Exporter; @ISA = qw(Exporter); @EXPORT_OK = qw(Parse); -use Parse::Pidl::Util qw(print_uuid); +use Parse::Pidl::Util qw(print_uuid has_property ParseExpr); use Parse::Pidl::Typelist qw(mapTypeName); +use Parse::Pidl qw(error fatal); +use Parse::Pidl::NDR qw(ContainsPipe GetNextLevel); +use Parse::Pidl::Samba4 qw(ElementStars); +use Parse::Pidl::Samba4::Header qw(GenerateFunctionOutEnv); use vars qw($VERSION); $VERSION = '1.0'; @@ -33,12 +37,115 @@ sub new($) bless($self, $class); } +sub decl_level($$) +{ + my ($self, $e, $l) = @_; + my $res = ""; + + if (has_property($e, "charset")) { + $res .= "const char"; + } else { + $res .= mapTypeName($e->{TYPE}); + } + + my $stars = ElementStars($e, $l); + + $res .= " ".$stars unless ($stars eq ""); + + return $res; +} + +sub alloc_out_var($$$$$) +{ + my ($self, $e, $mem_ctx, $name, $env, $alloc_error_block) = @_; + + my $l = $e->{LEVELS}[0]; + + # we skip pointer to arrays + if ($l->{TYPE} eq "POINTER") { + my $nl = GetNextLevel($e, $l); + $l = $nl if ($nl->{TYPE} eq "ARRAY"); + } elsif + + # we don't support multi-dimentional arrays yet + ($l->{TYPE} eq "ARRAY") { + my $nl = GetNextLevel($e, $l); + if ($nl->{TYPE} eq "ARRAY") { + fatal($e->{ORIGINAL},"multi-dimentional [out] arrays are not supported!"); + } + } else { + # neither pointer nor array, no need to alloc something. + return; + } + + if ($l->{TYPE} eq "ARRAY") { + unless(defined($l->{SIZE_IS})) { + error($e->{ORIGINAL}, "No size known for array `$e->{NAME}'"); + $self->pidl("#error No size known for array `$e->{NAME}'"); + } else { + my $size = ParseExpr($l->{SIZE_IS}, $env, $e); + $self->pidl("$name = talloc_zero_array($mem_ctx, " . $self->decl_level($e, 1) . ", $size);"); + } + } else { + $self->pidl("$name = talloc_zero($mem_ctx, " . $self->decl_level($e, 1) . ");"); + } + + $self->pidl("if ($name == NULL) {"); + $self->indent(); + foreach (@{$alloc_error_block}) { + $self->pidl($_); + } + $self->deindent(); + $self->pidl("}"); + $self->pidl(""); +} + +sub gen_fn_out($$) +{ + my ($self, $fn, $alloc_error_block) = @_; + + my $hasout = 0; + foreach (@{$fn->{ELEMENTS}}) { + if (grep(/out/, @{$_->{DIRECTION}})) { + $hasout = 1; + } + } + + if ($hasout) { + $self->pidl("NDR_ZERO_STRUCT(r2->out);"); + } + + foreach (@{$fn->{ELEMENTS}}) { + my @dir = @{$_->{DIRECTION}}; + if (grep(/in/, @dir) and grep(/out/, @dir)) { + $self->pidl("r2->out.$_->{NAME} = r2->in.$_->{NAME};"); + } + } + + foreach (@{$fn->{ELEMENTS}}) { + next if ContainsPipe($_, $_->{LEVELS}[0]); + + my @dir = @{$_->{DIRECTION}}; + + if (grep(/in/, @dir) and grep(/out/, @dir)) { + # noop + } elsif (grep(/out/, @dir) and not has_property($_, "represent_as")) { + my $env = GenerateFunctionOutEnv($fn, "r2->"); + $self->alloc_out_var($_, "r2", "r2->out.$_->{NAME}", $env, $alloc_error_block); + } + + } +} + ##################################################### # generate the switch statement for function dispatch sub gen_dispatch_switch($) { my ($self, $interface) = @_; + my @alloc_error_block = ("status = NT_STATUS_NO_MEMORY;", + "p->fault_state = DCERPC_FAULT_CANT_PERFORM;", + "goto fail;"); foreach my $fn (@{$interface->{FUNCTIONS}}) { next if not defined($fn->{OPNUM}); @@ -54,6 +161,8 @@ sub gen_dispatch_switch($) $self->deindent(); $self->pidl("}"); + $self->gen_fn_out($fn, \@alloc_error_block); + $self->pidl_hdr("struct $fname;"); if ($fn->{RETURN_TYPE} && $fn->{RETURN_TYPE} ne "void") { |