From 7bb2ebb884c35676a6cf03efe6ecc15b3e232a43 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Apr 2008 16:00:07 +0200 Subject: Fix size to memcpy call in generated Samba 3 client code. Reported-By: vl (This used to be commit a28807569d0cf32968bacdc0bd88197b19fbae49) --- source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm | 65 ++++++++++++++----------- source4/pidl/tests/samba3-cli.pl | 13 ++++- 2 files changed, 47 insertions(+), 31 deletions(-) diff --git a/source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm b/source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm index 7a2575b897..87ed29b54e 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm @@ -9,7 +9,7 @@ package Parse::Pidl::Samba3::ClientNDR; use Exporter; @ISA = qw(Exporter); -@EXPORT_OK = qw(ParseFunction $res $res_hdr); +@EXPORT_OK = qw(ParseFunction $res $res_hdr ParseOutputArgument); use strict; use Parse::Pidl qw(fatal warning); @@ -73,6 +73,40 @@ sub HeaderProperties($$) } } +sub ParseOutputArgument($$$) +{ + my ($self, $fn, $e) = @_; + my $level = 0; + + fatal($e->{ORIGINAL}, "[out] argument is not a pointer or array") if ($e->{LEVELS}[0]->{TYPE} ne "POINTER" and $e->{LEVELS}[0]->{TYPE} ne "ARRAY"); + + if ($e->{LEVELS}[0]->{TYPE} eq "POINTER") { + $level = 1; + if ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") { + $self->pidl("if ($e->{NAME} && r.out.$e->{NAME}) {"); + $self->indent; + } + } + + if ($e->{LEVELS}[$level]->{TYPE} eq "ARRAY") { + # This is a call to GenerateFunctionInEnv intentionally. + # Since the data is being copied into a user-provided data + # structure, the user should be able to know the size beforehand + # to allocate a structure of the right size. + my $env = GenerateFunctionInEnv($fn, "r."); + my $size_is = ParseExpr($e->{LEVELS}[$level]->{SIZE_IS}, $env, $e->{ORIGINAL}); + $self->pidl("memcpy($e->{NAME}, r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));"); + } else { + $self->pidl("*$e->{NAME} = *r.out.$e->{NAME};"); + } + + if ($e->{LEVELS}[0]->{TYPE} eq "POINTER") { + if ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") { + $self->deindent; + $self->pidl("}"); + } + } +} sub ParseFunction($$$) { @@ -147,36 +181,9 @@ sub ParseFunction($$$) $self->pidl("/* Return variables */"); foreach my $e (@{$fn->{ELEMENTS}}) { next unless (grep(/out/, @{$e->{DIRECTION}})); - my $level = 0; - fatal($e->{ORIGINAL}, "[out] argument is not a pointer or array") if ($e->{LEVELS}[0]->{TYPE} ne "POINTER" and $e->{LEVELS}[0]->{TYPE} ne "ARRAY"); - - if ($e->{LEVELS}[0]->{TYPE} eq "POINTER") { - $level = 1; - if ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") { - $self->pidl("if ($e->{NAME} && r.out.$e->{NAME}) {"); - $self->indent; - } - } + $self->ParseOutputArgument($fn, $e); - if ($e->{LEVELS}[$level]->{TYPE} eq "ARRAY") { - # This is a call to GenerateFunctionInEnv intentionally. - # Since the data is being copied into a user-provided data - # structure, the user should be able to know the size beforehand - # to allocate a structure of the right size. - my $env = GenerateFunctionInEnv($fn, "r."); - my $size_is = ParseExpr($e->{LEVELS}[$level]->{SIZE_IS}, $env, $e->{ORIGINAL}); - $self->pidl("memcpy($e->{NAME}, r.out.$e->{NAME}, $size_is);"); - } else { - $self->pidl("*$e->{NAME} = *r.out.$e->{NAME};"); - } - - if ($e->{LEVELS}[0]->{TYPE} eq "POINTER") { - if ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") { - $self->deindent; - $self->pidl("}"); - } - } } $self->pidl(""); diff --git a/source4/pidl/tests/samba3-cli.pl b/source4/pidl/tests/samba3-cli.pl index f5b51b7d34..80725d28cf 100755 --- a/source4/pidl/tests/samba3-cli.pl +++ b/source4/pidl/tests/samba3-cli.pl @@ -4,12 +4,12 @@ use strict; use warnings; -use Test::More tests => 8; +use Test::More tests => 9; use FindBin qw($RealBin); use lib "$RealBin"; use Util; use Parse::Pidl::Util qw(MyDumper); -use Parse::Pidl::Samba3::ClientNDR qw(ParseFunction); +use Parse::Pidl::Samba3::ClientNDR qw(ParseFunction ParseOutputArgument); use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv); # Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work @@ -117,3 +117,12 @@ is($x->{res}, } "); + +$x = new Parse::Pidl::Samba3::ClientNDR(); + +$fn = { NAME => "bar", ELEMENTS => [ ], RETURN_TYPE => "WERROR" }; +my $e = { NAME => "foo", ORIGINAL => { FILE => "f", LINE => -1 }, + LEVELS => [ { TYPE => "ARRAY", SIZE_IS => "mysize" }, { TYPE => "DATA", DATA_TYPE => "int" } ]}; + +$x->ParseOutputArgument($fn, $e); +is($x->{res}, "memcpy(foo, r.out.foo, mysize * sizeof(*foo));\n"); -- cgit